Шаблон фабричного дизайна и ключевое слово «новый» - PullRequest
6 голосов
/ 01 января 2012

Я начинающий программист.Я знаю основы ООП, но пока не знаю «лучших практик».Например, одна парадигма, которая продолжает появляться в программировании, - это шаблон проектирования «Абстрактная фабрика», который кажется довольно простым.Одно из ключевых намерений - избегать ключевого слова «новый», потому что оно считается вредным.Я никогда не слышал этого на курсах по программированию.Может ли кто-нибудь уточнить этот момент?Почему мы хотим избежать создания экземпляров объектов в этой форме?

Ответы [ 6 ]

9 голосов
/ 01 января 2012

Рассмотрим в своем классе клиента / абонента, что вы пишете:

Vehicle v = new Car("BMW");

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

В качестве альтернативы вы используете фабричный шаблон , код которого выглядит примерно так:

Vehicle v = Factory.getVehicle();

Теперь вы можете сохранить логику отвода автомобиля (слабая сцепка) от клиента, и вашему клиенту никогда не понадобятся изменения в случае, если вам придется обновить конечный автомобиль, который вы получите.Обновится только реализация Factory, и ваши клиенты будут работать как есть.

4 голосов
/ 01 января 2012

Предлагаю прочитать эту статью: http://www.codinghorror.com/blog/2005/09/head-first-design-patterns.html

ключевая часть: Лучший способ научиться писать простой код - это написать простой код!Следует избегать шаблонов, как и всех форм сложности, до тех пор, пока они не станут абсолютно необходимыми. Это первое, что нужно освоить начинающим.Не последнее.

Я согласен с этим - завод нужен только тогда, когда он действительно нужен.

Хорошо, возвращаясь к теме, ключевое слово new может быть злым, но в большинстве случаев оно, безусловно, не является и не должно быть источником головной боли.Видя

List <Person> persons = new ArrayList<Person>();

Прекрасно.Даже не смей думать о фабричном производстве ArrayList или LinkedList.Это было бы полностью переоценено.

" Я видел множество систем, в которых шаблон Factory использовался слишком часто. Например, если каждый объект в системе создается с помощью Factory вместо прямого создания экземпляра (например, new StringNode (Probably)), система, вероятно, имеет переизбыток фабрик."@ Joshua Kerievsky

Не добавляйте шаблоны преждевременно, если вы не уверены, что это хорошая идея, и вы не можете быть уверены вэто без достаточного опыта.Начинаем писать код с шаблонами в своем уме - вроде: Factory, это здорово, давайте посмотрим, когда я смогу его разместить! - это не очень хорошая идея :).Лучше было бы добавить шаблоны в места в вашем коде, которые вызывают проблемы, когда вы чувствуете (запах :) - запах кода), что это можно сделать как-то лучше.То есть рефакторинг к шаблонам .

Об этом есть отличная книга, и я дам вам ссылку на главу " Переместить Знание создания на фабрику "

http://www.informit.com/articles/article.aspx?p=1398606&seqNum=2

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

4 голосов
/ 01 января 2012

Я бы не сказал, что new считается вредным. То, что пытается сделать шаблон абстрактной фабрики, - это решить проблему, состоящую в том, что new не может быть переопределено (т.е. не совместимо с виртуальной диспетчеризацией, по крайней мере, в таких языках, как Java и C #).

Рассмотрим этот пример кода (C #):

class Sender
{
    private ISendChannel channel;

    public Sender()
    {
    }

    public void Connect(Uri endpointAddress)
    {
        // !! Sender is tightly coupled to TCP implementation
        // !! even though it doesn't apparently have to be.
        this.channel = new TcpSendChannel(endpointAddress);
    }

    /* ... */
}

В этом коде у нас есть базовый интерфейс ISendChannel, чтобы разрешить прямую связь с какой-либо конечной точкой. Однако реализация в том виде, в котором она дана, является фиксированной, чтобы всегда использовать канал TCP, несмотря ни на что. Это нежелательно, потому что теперь, если вам нужен отправитель HTTP, вам нужно либо изменить класс Sender, либо добавить в него новые методы. Это «плохая связь».

Вместо этого вы можете использовать фабрику для создания каналов и передавать их отправителю. Отправитель попросит фабрику создать канал и таким образом отказаться от этой ответственности. Новая реализация может выглядеть так:

class Sender
{
    private readonly ISendChannelFactory factory;
    private ISendChannel channel;

    public Sender(ISendChannelFactory factory)
    {
        this.factory = factory;
    }

    public void Connect(Uri endpointAddress)
    {
        // Sender does not have to care what type of channel it is.
        this.channel = this.factory.CreateSendChannel(endpointAddress);
    }

    /* ... */
}

Теперь, чтобы использовать канал HTTP, вы можете создать экземпляр отправителя, используя другой тип фабрики, например, new Sender(new HttpSendChannelFactory(/* ... */));. HttpSendChannelFactory может затем вернуть HttpSendChannel (конкретный тип, производный от ISendChannel) из его CreateSendChannel метода.

1 голос
/ 01 января 2012

Чтобы понять этот шаблон или что-то не так с использованием ключевого слова new, вам не хватает необходимой обязательной парадигмы программирования, которая является Программирование с использованием интерфейса

Изучите это, и как только вы поймете, что это такое, вы поймете, что единственный способ действительно применять / следовать ему, это избегать использования new в вашем коде, т.е. кодовой связи.

0 голосов
/ 01 января 2012

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

Таким образом, стандартный шаблон фабрики будет возвращать конкретный класс, например

SomeType SomeVar = SomeFactory.CreateSomeType();

Где в качестве абстрактного фабричного шаблона будет

SomeInterface SomeVar = AbstractFactory.CreateSomeInterface ();

Таким образом, вместо SomeType, предоставляемого потребителю, только интерфейсявляется.Просто более высокий уровень абстракции, это все, полезно, но только вредно, ЕСЛИ вы не хотите, чтобы фабричный потребитель знал о SomeType.

0 голосов
/ 01 января 2012

Ну, насколько я знаю, в новом ключевом слове нет ничего плохого.Я говорю как разработчик PHP.В новом ключевом слове нет ничего плохого, и с ним нет проблем с безопасностью.

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

И в фоновом режиме вы все равно используете новое ключевое слово :)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...