我甚至不確定要搜索什麼關於這個問題,所以我想我會在這裏發佈。這是動態類還是...?
比方說,我有一大堆的接口等...
/// <summary>
/// All interesting classes will implement this interface
/// </summary>
interface IMasterInterface {}
/// <summary>
/// Interface to represent someone that creates/produces goods
/// </summary>
interface IProduceGoods : IMasterInterface { int Prop1 {get;} }
/// <summary>
/// Interface to represent someone that buys/consumes goods
/// </summary>
interface IConsumeGoods : IMasterInterface { int Prop2 {get;} }
/// <summary>
/// Interface to represent someone that stores goods
/// </summary>
interface IStoreGoods : IMasterInterface { double Prop3 {get;} string name {get;}}
/// <summary>
/// Interface to represent someone that enjoys looking at goods
/// </summary>
interface IEnjoyLookingAtGoods : IMasterInterface { int Prop4 {get;} DateTime Prop5 {get;} }
現在,我今天一定的組合,我知道我想要的,是這樣的:
/// <summary>
/// Class to represent a farm which grows and stores crops
/// </summary>
class Farm : IProduceGoods, IStoreGoods {/*...*/}
/// <summary>
/// Class to represent a merchant who buys goods and stores them
/// </summary>
class Merchant : IConsumeGoods, IStoreGoods {/*...*/}
/// <summary>
/// Window Shopper represents someone who doesn't buy anything and only looks
/// </summary>
class WindowShopper : IEnjoyLookingAtGoods{ /*...*/ }
現在我很高興我有幾堂課,但明天我想,如果有人從商家那裏買了一堂課,那麼我會去我的代碼,然後加上
/// <summary>
/// Princesses have lots of money to buy stuff and lots of time to look at stuff
/// </summary>
class Princess : IEnjoyLookingAtGoods, IConsumeGoods {/*...*/}
現在,我不認爲我應該這樣做...
我希望做的是有一個工廠(或類似)的事情,並說:
IMasterInterface princess = MyFactory.Create(IEnjoyLookingAtGoods, IEnjoyLookingAtGoodsParameters, IConsumeGoods, IConsumeGoodsParameters)
/// This should be true
((princess is IEnjoyLookingAtGoods) && (princess is IConsumeGoods))
從本質上講,我想告訴工廠使用哪些接口來構建對象。我有容器有IMasterInterface列表
/// <summary>
/// My container class for interesting objects
/// </summary>
class InterestingObjectContainer
{ public ReadOnlyCollection<IMasterInterface> InterestingObjects {get;} }
現在,這裏是問題的關鍵所在。讓所有感興趣的類實現IMasterInterface的原因是能夠擁有一個List並使用更具體的接口作爲過濾器。或許下面會更清楚:
/// <summary>
/// I want to see the net population of producers and get there total production
/// </summary>
class ProducerProductionCalculator
{
// THIS IS WHERE THE MEAT OF THE QUESTION RESIDES!
ProductionResults Calculate(InterestingObjectContainer interestingObject)
{
List<IProduceGoods> producers = interestingObject.InterestingObjects.OfType<IProduceGoods>(); // Perhaps more interest LINQ
return DoSomethingWithListToAggregate(producers);
}
}
通過濾除,以更具體的接口,我可以傳遞給 DoSomethingWithListToAggregate(ICollection的生產商)的所有對象的IProduceGoods的 具有方法/屬性現在算類。
我想過用字典和字符串屬性查找來實現這一點,但感覺就像我可以用這種方式編寫更強大的類型化代碼,並確保在某處存在一個簡單的拼寫錯誤不會混淆所有內容。
總之,我想總結的是:
這是實施對象上不同屬性的一個好辦法,如果因此這將是一個更好的。如果沒有,是否有辦法在工廠中創建對象,正如我上面試圖解釋的那樣?
編輯:
我看到一些OKS到這樣的想法,這很酷。我想知道如何創建一個只有屬性的接口的參數,並且屬性只有getter(我認爲這很重要)以及屬性的屬性值,並返回一個實現該接口的對象並具有所有屬性定義的屬性。
例如,
/// <summary>
/// Factory to create any combination of properties
/// </summary>
class FactoryForInterestingObjects
{
public static IMasterInterface Create(
List<KeyValuePair</*what goes here is the interface that I want to use,
what goes here are the parameter values that
should be returned by the getter */>>);
}
我合格出廠的所有接口和它們的參數值,它會創建一些類實現這些接口並具有這些值。希望這個更清楚一點?
編輯2:如何使用裝飾者?
從我看到的裝飾器中,您可以擴展對象的功能。這很酷。但是,您必須提前知道如何擴展該功能。你不能任意做這件事。
請考慮我的代碼庫如上,我想使用裝飾器。
我會說:
// Edited to be correct
class EnjoyLookingDecorator : IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public EnjoyLookingDecorator(IMasterInterface wrappedObject)
{ this.instance = wrapped Object;}
#region Implementation of IEnjoyLookingAtGoods
/*...*/
#endregion
}
編輯4:
我仍然不認爲這會工作。在你的例子中,我失去了包含的類接口,我不得不重定向它。例如,
class EnjoyLookingDecorator : IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public EnjoyLookingDecorator(IMasterInterface concrete)
{ this.instance = concrete;}
#region Implementation of IEnjoyLookingAtGoods here
/*...*/
#endregion
bool Is<T>() //this should be in the IMasterInterface
{
return this is T or instance is T;
}
}
class ConsumesGoodsDecorator : IConsumeGoods
{
private IMasterInterface instance;
public ConsumesGoodsDecorator (IMasterInterface concrete)
{ this.instance = concrete;}
#region Implementation of IConsumeGoods here
/*...*/
#endregion
bool Is<T>()
{
return this is T or instance is T;
}
}
所以當你D
IMasterInterface princess = new MasterClass() //whatever your concrete type is named
princess = new ConsumesGoodsDecorator(new EnjoyLookingDecorator(princess))
你不再能做到princess.PropertyOnIEnjoyLookingDecoratorInterface你失去所有這些屬性。這不是我想要的。保留屬性的唯一方法是重定向
class ConsumesGoodsDecorator : IConsumeGoods, IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public ConsumesGoodsDecorator (IMasterInterface concrete)
{ this.instance = concrete;}
#region Implementation of IConsumeGoods here
/*...*/
#endregion
#region Redirect all the IEnjoyLookingAtGoods Property Getters to instance
/* ... */
#endregion
bool Is<T>()
{
return this is T or instance is T;
}
}
通過執行重定向,我們必須實現接口。然後組合必須都有代碼,這正是我想要避免的。我不會對接口的組合有任何限制。
編輯5:
也許我仍然不清楚我的問題。試想接口,因爲它們上面有它們的屬性填充
如果工廠可以做這樣的事情:
/// <summary>
/// Factory to create any combination of properties
/// </summary>
class FactoryForInterestingObjects
{
public static IMasterInterface Create(
List<KeyValuePair<Type t, ArgSet customArguments>> interfaces))
{
object baseObject;
foreach(KeyValuePair<Type, ArgSet> interface in interfaces)
{
AddInterface(interface, object);
}
}
private static void AddInterface(KeyValuePair<Type, ArgSet> interface, ArgSet arguments)
{
// Delegate this to someone else
if(interface.Key is typeof(IProduceGoods))
{
IProduceGoodsExtensions.AddInterface(o, interface.value);
}
}
}
public static class IProduceGoodsExtensions
{
public static void AddInterface(object o, ArgSet arguments)
{
// do something to object to make it implement IProductGoods
// and make all the getters return the arguments passed in ArgSet
}
}
我知道這是不是它是如何將實際工作,但足以說明我點試圖製造。我希望對象實現接口的動態組合,併爲設置者設置默認值。
即使我能這樣做有工廠編寫包含代碼的文本文件:
/// <summary>
/// Auto Generated by Factory to create a new type on the fly
/// </summary>
class ClassImplementingIProduceGoodsAndIEnjoyLookingAtGoods : IProduceGoods, IEnjoyLookingAtGoods
{
// From IProduceGoods
public int Prop1 {get; private set;}
// From IEnjoyLookingAtGoods
public int Prop4 {get; private set;}
public DateTime Prop5 {get; private set;}
public ClassImplementingIProduceGoodsAndIEnjoyLookingAtGoods(int prop1, int Prop4 , DateTime Prop5)
{
this.Prop1 = prop1; this.Prop4 = Prop4; this.Prop5 = Prop5;
}
}
然後編譯類,並以某種方式讓我來創建它的實例。這就是我要找的。希望這更有意義。
編輯6:
這是解決方案,我可能會以來,我沒有看到在這一點上的替代去。現在
//Update Master Interface
interface IMasterInterface
{
bool Is(Type t);
IMasterInterface As(Type t);
}
/// <summary>
/// Class to build up a final object
/// </summary>
class CompositionObject : IMasterInterface
{
ICollection<IMasterInterface> parts;
CompositionObject(IMasterInterface object){ parts = new List<IMasterInterface(object);}
bool Is(Type t)
{
foreach(IMasterInterface part in parts)
{ if (part is t) return true; // not sure on this off top of head
}
return false;
}
IMasterInterface As(Type t)
{
foreach(IMasterInterface part in parts)
{ if(part is t) return part; }
}
bool Add(IMasterInterface interface)
{ this.Is(typeof(interface)) return false; // don't add again
this.parts.Add(interface) }
}
我廠可以只返回這些組成對象只要作爲被調用,我可以再低垂安全。我覺得可能有一種方法可以使用泛型來避免投射。
實現IMasterInterface的任何具體類都可以在調用As時簡單地返回自己。編輯3:
感謝大家的意見。我很高興我發佈了我對模式的無知; D感謝您的澄清!我喜歡這個網站和你所有可愛的人!
爲什麼你不能與做法最終你使用'InterestingObjects.OfType()'提及? –
sll
@sll:我不知道如何製造工廠。這就是問題所在。或者如果這是一個好方法。 – MPavlak
你期望在所有這些接口之間有什麼不同?除了getters? –