Когда использовать шаблон метода Factory? - PullRequest
34 голосов
/ 05 октября 2009

Когда использовать шаблон метода Фабрики?

Пожалуйста, дайте мне конкретную идею, когда использовать его в проекте? и как это лучше, чем новое ключевое слово?

Ответы [ 11 ]

35 голосов
/ 05 октября 2009

У меня есть два случая, когда я склонен использовать это:

  1. Объект должен быть инициализирован определенным образом
  2. Когда я хочу создать определенный тип на основе абстрактного типа (абстрактный класс или интерфейс).

Примеры: 1011 *
*

  1. Первый случай может означать, что вы хотите иметь фабрику, создающую SqlCommand объекты, к которым вы автоматически присоединяете действительный SqlConnection перед возвратом объекта команды.

  2. Второй случай - это если у вас определен интерфейс и во время выполнения определяется, какую именно реализацию интерфейса использовать (например, указав его в файле конфигурации).

34 голосов
/ 19 мая 2011

Используйте фабричный метод (не абстрактную фабрику), если вы хотите повторно использовать общие функции с различными компонентами.

Пример: Представьте, что у вас есть винтовка M16. Как то так:

public class M16
{
    private Scope scope = new StandardScope();
    private SecondaryWeapon secondary = new Bayonet();
    private Camouflage camo = new DesertCamo();

    public double getMass()
    {
        // Add the mass of the gun to the mass of all the attachments.
    }

    public Point2D shootAtTarget(Point2D targetPosition)
    {
        // Very complicated calculation taking account of lots of variables such as
        // scope accuracy and gun weight.
    }
}

Вы можете быть довольны этим некоторое время, думая, что вы не хотите ничего менять. Но затем вы должны выполнить секретную ночную миссию скрытности в джунглях, и вы понимаете, что ваши привязанности совершенно неуместны. Вам действительно нужны прицел NightVision, JungleCamo и дополнительное оружие GrenadeLauncher. Вам придется скопировать код из вашего оригинального M16 ...... не очень хорошая расширяемость ..... Фабричный метод на помощь!

Перепишите свой класс M16:

public abstract class M16
{
    private Scope scope = getScope();
    private SecondaryWeapon secondary = getSecondaryWeapon();
    private Camouflage camo = getCamouflage();

    public double getMass()
    {
        // Add the mass of the gun to the mass of all the attachments.
    }

    public Point2D shootAtTarget(Point2D targetPosition)
    {
        // Very complicated calculation taking account of lots of variables such as
        // scope accuracy and gun weight.
    }

    // Don't have to be abstract if you want to have defaults.
    protected abstract Scope getScope();
    protected abstract SecondaryWeapon getSecondaryWeapon();
    protected abstract Camouflage getCamouflage();
}


//Then, your new JungleM16 can be created with hardly any effort (and importantly, no code //copying):

public class JungleM16 : M16
{
    public Scope getScope()
    {
        return new NightVisionScope();
    }

    public SecondaryWeapon getSecondaryWeapon()
    {
        return new GrenadeLauncher();
    }

    public Camouflage getCamouflage()
    {
        return new JungleCamo();
    }
}

Основная идея? Настраивайте и меняйте составные объекты, сохраняя при этом общую функциональность

Действительно полезное место для его использования: Вы только что разработали действительно классный графический интерфейс, и он имеет действительно сложную компоновку. Было бы очень больно иметь все заново, если вы хотите иметь разные виджеты. Итак ..... используйте фабричный метод для создания виджетов. Затем, если вы передумаете (или кто-то еще захочет использовать ваш класс, но использовать другие компоненты), вы можете просто создать подкласс GUI и переопределить методы фабрики.

24 голосов
/ 05 октября 2009

Вы можете обратиться к разделу 9.5 Фабрики из Руководства по проектированию платформы, 2-е издание. Вот приведенный набор рекомендаций по использованию фабрик над конструкторами:

предпочитаю конструкторов заводы, потому что они как правило, более удобный, последовательный, и удобнее, чем специализированный строительные механизмы.

РАССМОТРИТЕ использование фабрики, если вам нужно больше контроля, чем может быть обеспечено конструкторы над созданием экземпляры.

Используйте фабрику в случаях, когда разработчик может не знать, какой тип построить, например, при кодировании по базовому типу или интерфейсу.

РАССМОТРИТЕ использование фабрики, если именованный метод - единственный способ сделать операция не требует пояснений.

используйте фабрику для конверсии операции.

А из раздела 5.3 Конструктор конструктора

УЧИТЫВАЙТЕ использование статического метода фабрики вместо конструктора, если семантика желаемой операции не отображается непосредственно на конструкцию новый экземпляр или, если он следует руководству по проектированию конструктора чувствует себя неестественно.

16 голосов
/ 05 октября 2009

Хотя это не обязательно его основное использование, оно хорошо для того, где у вас есть специализированные экземпляры класса:

public ITax BuildNewSalesTax()
public ITax BuildNewValueAddedTax()

Вам нужны оба метода для создания объекта налога, но вам не нужно зависеть от использования «нового» каждый раз, потому что конструкторы могут быть сложными. Таким образом, я инкапсулирую все изменения в единый метод, понятный другим для дальнейшего обслуживания.

6 голосов
/ 17 сентября 2010

Я использую фабричные патенты, когда

  1. Когда класс не знает, какой класс объектов он должен создать.

  2. Класс указывает свои подклассы, чтобы указать, какие объекты создавать.

  3. На языке программиста (очень сырая форма) вы можете использовать фабричный шаблон, где вам необходимо создать объект любого из подклассов в зависимости от предоставленных данных.

3 голосов
/ 29 ноября 2010

Шаблон метода фабрики можно использовать, когда необходимо сгенерировать объекты, принадлежащие к определенному семейству. Наряду с этим требованием вы также хотите сохранить решения, принятые в отношении создания объектов, в одном месте.

Пожалуйста, обратитесь к следующей ссылке для получения более подробной информации.

http://xeon2k.wordpress.com/2010/11/27/factory-method-pattern/

2 голосов
/ 05 июля 2017

Фабричный шаблон имеет дело с созданием объекта без раскрытия логики создания. Другими словами, Фабрика на самом деле является создателем объекта, который имеет общий интерфейс.

Позволяет подклассу решить, какой класс будет создан.

Рассмотрим следующий пример:

namespace TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //Store is ordering the factory to get office shoes
            Shoe shoe = ShoeFactory.GetShoes("OFFICE");
            Console.WriteLine(shoe.GetType()); //Will be office shoes

            //Store is ordering the factory to get sports shoes
            shoe = ShoeFactory.GetShoes("SPORTS");
            Console.WriteLine(shoe.GetType()); //Will be sports shoes
        }
    }

    //This is the factory supplying shoes. It can supply sports shoes or office shoes
    //based on demand
    class ShoeFactory
    {
        public static Shoe GetShoes(string strShoeType)
        {
            switch (strShoeType)
            {
                case "SPORTS": return new SportShoe();
                    break;
                case "OFFICE": return new OfficeShoe();
                    break;
                default:
                    return null;
            }
        }
    }

    //This is an abstract class representing product family
    //In this example, its shoe
    public abstract class Shoe
    {

    }

    //Office shoe is a concrete class belongs to shoe family
    class OfficeShoe : Shoe
    {   

    }

    //Sports shoe is a concrete class belongs to shoe family
    class SportShoe : Shoe
    {

    }
}
2 голосов
/ 05 октября 2009

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

1 голос
/ 05 октября 2009

Лучше иметь шаблон фабричного метода вместо нового ключевого слова. Идея состоит в том, чтобы переместить полную реализацию объектов за пределы бизнес-логики. Этот принцип является сутью зависимости внедрения . Кроме того, работа фабричного метода может быть позднее делегирована инфраструктуре внедрения зависимостей, такой как Spring.net или Castle Windsor.

0 голосов
/ 12 марта 2010

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

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

http://www.mixedwaves.com/2009/02/implementing-factory-design-pattern/

...