2013-11-30 4 views
1

Мне нужно создать одно из нескольких объектов на основе некоторого значения, и мне было рекомендовано изучить шаблоны Factory. Я не хочу, чтобы мой клиент, имеющий решить, какой объект создавать или требовать жестко закодированные имена классов, поэтому после того, как делают некоторые чтения я придумал следующее (упрощенный), например:Реализация фабричного шаблона

public class ObjectA : IObject 
{ 
} 

public class ObjectA : IObject 
{ 
} 

public interface IObjectFactory 
{ 
    IObject CreateObject(ObjectCreationParameters p); 
} 

public abstract ObjectFactory : IObjectFactory 
{ 
    abstract IObject CreateObject(ObjectCreationParameters p); 
} 

public ConcreteObjectFactory : ObjectFactory 
{ 
    public IObject CreateObject(ObjectCreationParameters p) 
    { 
     IObject obj; 
     switch (p.Value) 
     { 
      case A: 
       obj = new ObjectA(); 
       break; 
      case A: 
       obj = new ObjectB() 
       break; 
     } 
     return obj; 
    } 
} 

Вышеприведенные работает, но я я немного смущен относительно того, правильна ли моя реализация или нет.

Я предпочел бы не иметь ObjectAFactory и ObjectBFactory как в Factory Method шаблоне, если этого можно избежать, однако, моя иерархия объектов, кажется, не следовать той же иерархии объектов, как в примере Abstract Factory рисунка. У меня нет ObjectA2 или ObjectB2, которые можно было бы создать через ConcreteObject2Factory.

Является ли моя реализация правильной или я делаю что-то неправильно, и если да, то что?

+0

Цель фабрики - не допустить, чтобы вызывающий код беспокоился о том, как создать объект. Вызывающему не нужно указывать, какой класс он хочет создать. – usr

+0

вам нужно проверить разницу между заводским шаблоном метода и абстрактным заводским шаблоном. эта ссылка имеет хорошее объяснение http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method –

ответ

0

Да, это правильная реализация. Это switch утверждение может показаться проблематичным и не полиморфный, но на самом деле, вы можете прочитать об этом в отличном Code Clean book, правило G23: Предпочитают полиморфизма If/Else или коммутатору/Case:

«ONE SWITCH ": может быть не более одного оператора switch для определенного типа выбора. Случаи в этом операторе switch должны создавать полиморфные объекты, которые заменяют другие аналогичные операторы в остальной части системы.

Ваша реализация абстрактного создания конкретного объекта, клиент-клиент не должен беспокоиться об этом, и для этого и предназначен этот шаблон дизайна. Посмотрите также, например, в разделе Инкапсуляция в Wikipedia entry.

0

Что вы действительно хотите посмотреть - это инверсия управления (IoC); по существу, это фабричная модель, но ее естественный вывод.

Просто зарегистрируйте все свои типы с контейнером IoC и затем делегируйте задачу их создания. В приятном современном приложении вы нередко создаете объекты (и почти никогда не указываете их явно), и вы никогда не остерегаетесь их зависимостей, все это делается для вас.

В C# мой любимый контейнер IoC - Autofac Я долгое время использовал его в проекте по гребле, и он в значительной степени просто продолжает делать то, что ему нужно. Есть и другие, но я бы сказал, что это хорошее место для начала.

+0

Я не упомянул, что значения, используемые для создания объектов, будут определены во время выполнения , Не влияет ли ваше предложение на использование контейнера IoC? – Unflux

+0

Нет, вы можете указать некоторые или все параметры конструктора во время выполнения с помощью контейнера IoC (https://code.google.com/p/autofac/wiki/DelegateFactories). – briantyler

+0

ОК спасибо, я посмотрю на это. – Unflux

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