2016-03-31 17 views
0

Projemde, özel özellikleri uygulayan sınıfların hiyerarşisi var. Konsol uygulaması için istediğim şeye daha yakın.OOP tasarım desenleriyle temel sınıf özelliği genişletilebilirlik mekanizmasının nasıl daha iyi uygulanacağı

class Property 
{ 
    string key; 
    object value; 

    public Property(string key, object value) 
    { 
     this.key = key; 
     this.value = value; 
    } 

    public override string ToString() 
    { 
     return "(key=" + key + ": value=" + value + ")"; 
    } 
} 

public struct PropertyConfig 
{ 
    public string key; 
    public object defaultValue; 
} 

abstract class BaseClass 
{ 
    Dictionary<string, Property> properties = new Dictionary<string, Property>(); 

    Dictionary<string, PropertyConfig> mergedConfigs = new Dictionary<string, PropertyConfig>(); 

    public BaseClass() 
    { 
     MergeWithInheritedConfigsAndCreateInstances(
      new PropertyConfig[] 
      { 
       new PropertyConfig() { key = "p1", defaultValue = "v1" }, 
       new PropertyConfig() { key = "p2", defaultValue = "v2" } 
      }, 
      true); 
    } 

    protected void MergeWithInheritedConfigsAndCreateInstances(PropertyConfig[] configs = null, bool IsBaseClass = false) 
    { 
     configs = configs ?? new PropertyConfig[] { }; 

     foreach (PropertyConfig config in configs) 
     { 
      mergedConfigs[config.key] = config; 
     } 

     if (!IsBaseClass) 
     { 
      CreatePropertyInstancesAfterMerge(); 
     } 
    } 

    private void CreatePropertyInstancesAfterMerge() 
    { 
     foreach (KeyValuePair<string, PropertyConfig> kvp in mergedConfigs) 
     { 
      PropertyConfig config = kvp.Value; 

      properties.Add(config.key, new Property(config.key, config.defaultValue)); 
     } 
    } 

    public override string ToString() 
    { 
     return GetType().Name + ".Properties: " + string.Join(",", properties.Select(kvp => kvp.Value.ToString()).ToArray()); 
    } 
} 

class DerivedClassA : BaseClass 
{ 
    public DerivedClassA(): base() 
    { 
     MergeWithInheritedConfigsAndCreateInstances(); 
    } 
} 

class DerivedClassB : BaseClass 
{ 
    public DerivedClassB() : base() 
    { 
     MergeWithInheritedConfigsAndCreateInstances(new PropertyConfig[] 
     { 
      new PropertyConfig() { key = "p2", defaultValue = true }, 
      new PropertyConfig() { key = "p3", defaultValue = "v3" } 
     }); 
    } 
} 

class DerivedClassC : BaseClass 
{ 
    public DerivedClassC() : base() 
    { 
     MergeWithInheritedConfigsAndCreateInstances(new PropertyConfig[] 
     { 
      new PropertyConfig() { key = "p2", defaultValue = false }, 
      new PropertyConfig() { key = "p4", defaultValue = "v4" } 
     }); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     DerivedClassA derivedA = new DerivedClassA(); 
     DerivedClassB derivedB = new DerivedClassB(); 
     DerivedClassC derivedC = new DerivedClassC(); 

     Console.WriteLine(derivedA.ToString()); 
     Console.WriteLine(derivedB.ToString()); 
     Console.WriteLine(derivedC.ToString()); 


     Console.ReadLine(); 
    } 
} 

Taban soyut sınıf türetilmiş sınıfları kalıtsal amaçlanan kendi özellik nesnelerin bir konfigürasyon oluşturur.

Yapıcı yapılandırma dizisinde MergeWithInheritedConfigsAndCreateInstances yöntem çağrısı geçirilir, ikinci parametre true olarak ayarlanarak, özellik nesnelerinin başlatılmasının ertelenmesi gerektiğini belirtir.

Birleştirilen özellik yapılandırmasının geçerli durumu, mergedConfigsDictionary'da depolanır.

Türetilmiş sınıfları temel sınıf konfigürasyonu özelliği örnekleri birleştirme sonrasında oluşturulması gerekir belirten varsayılan değerine false ayarlanmış ikinci parametre ile Oluşturucu MergeWithInheritedConfigsAndCreateInstances yöntemi çağrı ile geçersiz/birleştirme yerel özelliği yapılandırmasını geçmektedir.

Ortaya çıkan çıktı aşağıdadır.

DerivedClassA.Properties: (key=p1: value=v1),(key=p2: value=v2) 
DerivedClassB.Properties: (key=p1: value=v1),(key=p2: value=True),(key=p3: value=v3) 
DerivedClassC.Properties: (key=p1: value=v1),(key=p2: value=False),(key=p4: value=v4) 

Ve ihtiyacım olan şey, ama ben sevmiyorum bu çözümün bazı dezavantajları vardır: Her yapıcı içinde MergeWithInheritedConfigsAndCreateInstances aramak gereklidir

1). İkinci parametre, soyut sınıf yapıcısında sağlanmalıdır.

Tüm birleştirme/somutlaştırma mekanizmasının temel sınıfta uygulandığı ve çağrıldığı bir çözüm bulmak istiyorum. Ve türetilmiş sınıf özel özellik yapılandırmasını bir yöntem parametresi olarak değil, üye alan/özellik (belki statik?) Olarak tanımlayabilmek.

2) Birleştirme işlemi her zaman sınıfı başlatılır.

Sadece bir kez yapmayı tercih ederim. (Statik kurucuya yerleştiriliyor musunuz?)

YUKARI: Yeniden yazılan örnek kod, daha iyi bir fikir ortaya koymaktadır.

+0

Bilginize: Bu XAML/WPF bağımlılık özellikleri ile kaputun altında işliyor .. –

+0

Kodumda wpf yapılarına güvenemiyorum. Gereksinimler benzer görünse de, wpf bağımlılık özelliği sisteminin iç uygulaması, alanlarına özgüdür ve uygulama ayrıntıları olduğu gibi burada tekrar kullanılamaz. –

+0

Bu, onların somut sınıflarını yeniden kullanmakla ilgili değildi, aksine arkasındaki fikir ...:/ –

cevap

2

Sanırım bir şeyleri fazlasıyla karmaşıklaştırıyorsunuz.

class BaseClass 
{ 
    private readonly Dictionary<string, string> properties = new Dictionary<string, string>(); 
    protected string this[string key] 
    { 
     get { string value; return properties.TryGetValue(key, out value) ? value : null; } 
     set { if (value == null) properties.Remove(key); else properties[key] = value; } 
    } 

    public BaseClass() 
    { 
     this["p1"] = "v1"; 
     this["p2"] = "v2"; 
    } 

    public override string ToString() 
    { 
     return GetType().Name + ".Properties: " + string.Join(",", properties.Select(kvp => $"{kvp.Key}:{kvp.Value}")); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public DerivedClass() : base() 
    { 
     this["p2"] = "update"; 
     this["p3"] = "v3"; 
    } 
} 

Ama açıkçası, bu basit ve daha açıktır: Hatta karmaşık bir kurulum için, bu yeterli olacaktır

class BaseClass 
{ 
    public string P1 {get;set;} 
    public string P2 { get; set; } 
    public BaseClass() 
    { 
     P1 = "v1"; 
     P2 = "v2"; 
    } 
    public override string ToString() 
    { 
     return GetType().Name + ".Properties: " + string.Join(",", GetType().GetProperties(
      BindingFlags.Public | BindingFlags.Instance).Select(p => $"{p.Name}:{p.GetValue(this)}")); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public string P3 { get; set; } 
    public DerivedClass() : base() 
    { 
     P2 = "update"; 
     P3 = "v3"; 
    } 
} 
+0

Teşekkürler! Tabii ki, kodu çok basitleştirdim. Görev bağımlılık özelliği sistemi uygulamaktır. Her özellik sınıfının mantığı vardır. Temel sınıf, farklı özellik değerleri için pub/sub, getters/setters uygular. Çapraz referans. Özellikler anında eklenebilir/kaldırılabilir. Bu soruyla, temel sınıfta tanımlanan özelliklerin başlatılmasını sağlayan ve bunları türetilmiş sınıfta tanımlanan özellik kümesiyle devralma/geçersiz kılma/birleştirmeye izin veren özellik sisteminin bir parçası için çözüm bulmam gerekiyor. Çok fazla basitleştirilmişse sorun ve yeniden formüle edeceğim. –

+0

soruyu güncelledi ve örnek –

İlgili konular