2015-03-31 4 views
-1

Я читал все, что я могу найти о Factory/Abstract Factory/Simple Factory/etc. Я не смог найти ответ на этот вопрос. Я понимаю, что классы, создаваемые фабрикой, должны реализовывать один и тот же интерфейс или получать один и тот же базовый класс. Но что происходит, если разные классы не имеют одного и того же открытого интерфейса? И.Е. SubClass1 и SubClass2 оба происходят из BaseClass. Теперь SubClass1 добавляет PropertyA и SubClass2 добавляет свойствоB. Правильно ли я предполагаю, что эти классы не могут быть созданы фабрикой, так как они не имеют тот же интерфейс? Или, если они были созданы как BaseClass, они не будут раскрывать свои новые свойства. Та же проблема существует с общим интерфейсом. И если кто-нибудь знает автора, который обращается к этому, я был бы признателен за ссылку.C# Factory Pattern новичок

Большое спасибо!

+2

Они все еще могут иметь один и тот же интерфейс. Если вы обращаетесь к ним через интерфейс, вы не можете увидеть дополнительные свойства – Ewan

+0

согласны с Ewan. Эти классы могут быть созданы на заводе, но без кастинга вы не можете использовать расширенные свойства (методы). Вы можете использовать кастинг, но для меня это выглядит как плохой подход. – Disappointed

+0

Я тоже согласен с Ewan, также Head First Design Patterns отлично подходит для объяснения нюансов шаблонов, включая Factory: http://www.amazon.co.uk/Head-First -Design-Patterns-Freeman/dp/0596007124 – majjam

ответ

1

Я думаю, что вы пропустили цель интерфейса. Если вы используете интерфейсы, может быть не лучше всего создавать классы, у которых есть общедоступные методы, которые не являются частью интерфейса.

Так что, если ваша фабрика производит IAnimal. Вы не должны предполагать, что вы получаете класс Dog, который реализует метод WagTail, или класс Cat, который LandsOnFeet. Вам необходимо определить IDog и ICat. (Возможно, наследуется от IAnimal).

Затем вы можете рассмотреть, как ведет себя ваша фабрика. У вас есть несколько вариантов.

А. Обобщения

Затем можно создать интерфейс IAnimalFactory Generic Factory, который при реализации возвращается либо IAnimal или конкретного типа.

public interface IAnimal 
    { 
     int Legs(); 
    } 

public interface IAnimalFactory<T> where T: IAnimal 
{ 
    IAnimal CreateAnimal(); 
    T CreateSpecificAnimal(); 
} 

public interface IDog:IAnimal 
{ 
    void WagTail(); 
} 

public interface ICat : IAnimal 
{ 
    void LandOnFeet(); 
} 

public class Dog:IDog 
{ 
//Implementation Excluded 
} 

public class Cat : ICat 
{ 
//Implementation Excluded 
} 

public class DogFactory:IAnimalFactory<IDog> 
{ 
    public IAnimal CreateAnimal() 
    { 
     return (IAnimal)CreateSpecificAnimal(); 
    } 

    public IDog CreateSpecificAnimal() 
    { 
     return new Dog(); 
    } 

} 

public class CatFactory : IAnimalFactory<ICat> 
{ 
    public IAnimal CreateAnimal() 
    { 
     return (IAnimal)CreateSpecificAnimal(); 
    } 

    public ICat CreateSpecificAnimal() 
    { 
     return new Cat(); 
    } 

} 

Типовая подход дает вам некоторое будущее корректуры, если вы потом решите реализовать IDomesticDog или IWildDog, и мои предпочтения, но может быть более сложным, чем это необходимо, в зависимости от ваших потребностей.

B. Конкретные методы в SubClass

Вы можете также создать фабрику, которая имеет функции, которые создают собаку или кошку типа IAnimal.

public class AnimalFactory 
    { 
     public IAnimal GetDog() 
     { 
      return (IAnimal) new Dog(); 
     } 

     public IAnimal GetCat() 
     { 
      return (IAnimal) new Cat(); 
     } 

    } 

Теперь, как указано выше, вы можете безопасно отнести к IDog или ICat.

Я не думаю, что есть один автор, который конкретно ответит на ваш вопрос. Однако чтение информации об инверсии контроля и зависимостей инъекций, скорее всего, даст вам нужный уровень необходимой вам информации.

+0

Я должен не согласиться с вашим утверждением: «Большинство классов должны реализовывать интерфейс». Если классу не требуется реализовать интерфейс, это правило просто приведет к большому количеству бесполезных интерфейсов. –

+0

Простой комментарий @BradleyUffner Я изменил соответствующим образом. – Spevy