![](/img/trans.png)
[英]OOP Design: Concrete Class having different Operations with Same Base Class
[英]How to better implement base class property extencibility mechanism with OOP design patterns
在我的項目中,我具有實現自定義屬性的類層次結構。 這里更接近我想要的控制台應用程序版本。
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();
}
}
基本抽象類定義其屬性對象的配置,這些屬性旨在在派生類中繼承。
在構造函數中,將數組傳遞給MergeWithInheritedConfigsAndCreateInstances
方法調用,並將第二個參數設置為true
指示必須延遲屬性對象的實例化。
合並屬性配置的當前狀態存儲在mergedConfigs
Dictionary
。
派生類將本地屬性配置傳遞給合並/覆蓋,而基類配置將在其構造函數中調用MergeWithInheritedConfigsAndCreateInstances
方法,並將第二個參數設置為其默認值false
指示現在必須在合並后創建屬性實例。
結果輸出如下。
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)
這就是我所需要的,但是我不喜歡這種解決方案的一些缺點:
1)必須在每個構造函數中調用MergeWithInheritedConfigsAndCreateInstances
。 必須在抽象類構造函數中提供第二個參數。
我想要一個在基類中實現並調用所有合並/實例化機制的解決方案。 為了能夠將派生類特定的屬性配置定義為不是方法參數,而是成員字段/屬性(也許是靜態的)。
2)每次實例化類時,都會完成合並過程。
我希望只完成一次。 (放置在靜態構造函數中?)
UPD:重新編寫的示例代碼可以更好地演示預期的想法。
我認為您太過復雜了。 即使對於復雜的設置,這也足夠了:
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";
}
}
但坦率地說,這更加簡單和明顯:
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";
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.