2011-02-02 1 views
17

Нужен ли заводской шаблон C# для повышения?C# завод - это upcast a must?

Я хочу, чтобы Бог в библиотеке классов G создал Адама в библиотеке классов A, не делая G зависимым от A. Бог производит Адамс для потребления Евой в библиотеке классов E, и Ева хорошо знать и зависеть от Адама. (edit - этот образец продолжает улучшаться и улучшаться :)

Решение, о котором я мог думать, имеет AdamFactory в A. Таким образом AdamFactory знает Адама и может легко его создать (возможно, просто вызвав конструктор Адама). Бог получает AdamFactory и может заказать его в CreateAdam.

Теперь, поскольку Богу не разрешено знать Адама, CreateAdam от AdamFacotry должен возвращать объект, и для этого требуется, чтобы Ева подняла объект, возвращенный AdamFactory, на Адама.

Это будет работать, я думаю. Тем не менее, я чувствую себя неловко из-за кастинга, поскольку это не-нет. Это действительно необходимо?

P.S. - Не было богохульства, и я извиняюсь, если чьи-то чувства пострадали. Казалось бы, лучше использовать Бога и Адама вместо Творца и Создано, потому что два последних слова слишком похожи друг на друга.

Редактировать: Re предлагает интерфейс. Предположим, что у Адама есть два метода: ProvideLove, ProvideFood и ProvideProtection (мы держим этот образец kis-safe :). Ева использует Адама для этих двух целей, но, конечно, Бог этого не делает. Итак, зачем предоставлять Богу знание о том, что AdamFactor возвращает то, что реализует IAdam, а не только объект? Я не понимаю!

Edit: рабочий код (со всеми в той же библиотеке, что моя цель состоит в том, чтобы отделить в различные библиотеки) выглядит примерно так:

Adam God.LoadAdam(AdamID theAdamID) 
     var adam = new Adam(theAdamId, this) 

Adam.Adam(AdamID theAdamID, God theGod) 
     _god = theGod 
     _mind = theGod.LoadMind(theAdamId, this) 

Mind God.LoadMind (AdamID theAdamID, Adam theAdam) 
     var mind = new Mind (theAdam) 
     var mindId = new minId(theAdamId) 
     mind.DeserializeFromFile(minId) 

Mind.Mind (Adam theAdam) 
     _adam = theAdam 
+2

Я считаю, вы имеете в виду * downcast * возвращенный объект для Адама. –

+0

Я бы пошел на интерфейсы, как указано в первом ответе. Во всяком случае, +1 для хорошего вопроса, очень смешно :-) – Shimrod

+3

Упрощенный вопрос для образца, даже перед его чтением до конца. :) – Stilgar

ответ

9

Я не уверен, что я полностью понять требования, но здесь это предложение:


//in assembly G 
public abstract class HumanFactory<T> 
{ 
    public abstract T CreateHuman(); 
} 

//in assembly A 
public class Adam { } 
//in assembly A 
public class AdamFactory : HumanFactory<Adam> 
{ 
    public override Adam CreateHuman() 
    { 
     return new Adam(); 
    } 
} 

//in assembly G 
public class God 
{ 
    public T Create<T>(HumanFactory<T> factory) 
    { 
     return factory.CreateHuman(); 
    } 
} 

и использование:


//Somewhere in assembly E 
Adam adam = new God().Create(new AdamFactory()); 
+0

+1 учитывая весь набор «Вопрос + комментарии» Я бы сказал, что это наиболее разумное решение. Тем не менее, в дизайне OP есть что-то не так, IMHO. – Simone

+0

@ Симон этот дизайн может иметь некоторые виды использования. Чтобы быть полезными, должны быть общие ограничения, основанные на общих интерфейсах или базовых классах для Адама и других экземплярах, созданных Богом.Тогда Бог может сделать какую-то другую работу, кроме слепого призыва в Адамфалла. Также базовый класс HumanFactory может иметь дополнительные методы, которые Бог может использовать для выполнения дополнительной работы. – Stilgar

+0

@ Симон, Бог может заставить Адама жить для каждого, сортируя информацию о стороне базы вещей и т. Д., Ева не может этого сделать, потому что она зафиксирована в сигле (но движущейся) точке на временной линии. –

1

Что об использовании интерфейсов и Бог знает IAdam, или что-то как IHuman?

+0

Бог не должен использовать Адама. Итак, как Бог мог бы воспользоваться интерфейсом? – Avi

1

Я думаю, вы могли бы использовать инъекцию зависимости. Попробуйте контейнер с инверсией контроля (IoC), например Unity 2, StructureMap, или Castle of Windsor.

+1

Очень простой пример был бы действительно оценен – Avi

0

Вы описываете abstract factory pattern, хотя «дочерние» фабрики (например, AdamFactory) обычно имеют что-то общее, поэтому вы ожидаете, что они производят нечто большее, чем обычный интерфейс, а не просто объект (см. Ответ Давиде)

Вы правы, чтобы беспокоиться о актерском составе, поскольку это свяжет Еву с реализацией Адама, которая побеждает цель фабрики (если вы действительно не используете ее как строителя).

Вопрос в том, зачем вам нужен класс Бога вообще?

0

Ну, если Бог есть библиотека классов живучесть, как вы упомянули в комментарий, то это не должно влиять на дизайн класса остальной системы.

Итак, я бы не добавил лишние интерфейсы. Это нормально возвращать объект из десериализатора и затем вниз (например,BinaryFormatter, XmlSerializer).

Лучшим способом было бы сделать ваш десериализатор общим.

0

ОК, а как насчет орошения в некоторых дженериках здесь?

Допустим, Бог может принять Фабрики любого типа Т, которые прилипают к следующему интерфейсу:

interface IFactory { 
    Type CreatedType { get; } 
    object Create(); 
} 

Абстрактный класс, чтобы осуществить это может выглядеть следующим образом:

abstract class AbstractFactory<T> : IFactory { 
    public Type CreatedType { get { return typeof(T); } 
    public virtual object Create() { 
    return innerCreate(); 
    } 
    protected abstract override T innerCreate(); 
} 

Теперь вы можете зарегистрировать фабрики с богом:

God.RegisterFactory(new AdamFactory()); 

AdamFactory наследует от AbstractFactory<Adam>

Бог хранит свои заводы в словаре, где ключ является тип, возвращаемый интерфейсом IFactory

Создать метод выглядит так:

God.Create<Adam>(); 

Бог смотрит на свои заводы, видит там является одним для typeof (T) общего метода, извлекает фабрику, вызывает создание и downcasts к T.

Как вы думаете?

+1

Но тогда вы почти начинаете строить контейнер IoC. По общему признанию, Бог - хорошее имя для контейнера IoC, но есть уже несколько таких ... – flq

+0

Бог, возможно, больше из Сервисного контейнера ... – DaeMoohn

Смежные вопросы