나는이 문제와 관련하여 무엇을 검색해야할지 모르겠다. 그래서 나는 그것을 여기 게시 할 것이라고 생각했다.동적 클래스 또는 ...의 경우입니까?
/// <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>
/// 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>
/// 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))
을 본질적 :3210
는 지금, 나는 내가하고 싶은 무엇
는 공장 (또는 유사한) 일을 가지고 말은 ... 내가 그렇게해야한다고 생각하지 않습니다 개체를 생성하는 데 사용할 인터페이스를 팩토리에 알려야합니다. 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를 참조하고 멋지다. 나는 단지 속성을 가진 인터페이스의 인수를 취하는 속성을 가진 팩토리를 만드는 방법을 궁금해했다. 속성은 속성에 대한 속성 값과 함께 getters (나는 중요한 포인트라고 생각한다)를 가지며 인터페이스를 구현하고 모든 속성이 정의되었습니다. 예를 들어
,
/// <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 : Decorator를 사용하는 방법?
데코레이터에 관해서는 객체의 기능을 확장 할 수 있습니다. 멋지다. 그러나 미리 기능을 확장하는 방법을 미리 알아야합니다. 이것을 임의로 할 수는 없습니다.
내 코드 기반이 위와 같고 데코레이터를 사용하려고한다고 가정합니다.
내가 말하고 싶지만 :
// Edited to be correct
class EnjoyLookingDecorator : IEnjoyLookingAtGoods
{
private IMasterInterface instance;
public EnjoyLookingDecorator(IMasterInterface wrappedObject)
{ this.instance = wrapped Object;}
#region Implementation of IEnjoyLookingAtGoods
/*...*/
#endregion
}
EDIT 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;
}
}
그래서 당신이
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
}
}
를이 실제로 어떻게 작동하는지가 아니라 내가 '점을 보여 나는하려고 애쓰다. 객체가 인터페이스의 동적 조합을 구현하고 setter에 대한 기본값을 갖기를 원합니다.
/// <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를 구현하는 구체적인 클래스는 호출 될 때 단순히 자신을 반환 할 수 있습니다.
편집 3 :
의견을 보내 주셔서 감사합니다.나는 패턴의 나의 무지를 게시했기 때문에 기쁘다, D 명확히 해 주셔서 감사합니다! 나는이 사이트와 당신의 모든 사랑스러운 사람들을 거기에서 사랑한다 !!
없이 파악하기 어렵다? – sll
@sll : 공장 제작 방법을 모르겠습니다. 그게 질문입니다. 또는 이것이 좋은 접근법이라면 말이다. – MPavlak
이 모든 인터페이스간에 어떤 차이가있을 것으로 예상됩니까? 그냥 게터 말고? –