Реализация паттерна "Фабрика" на Java в книгах
От: pooo  
Дата: 01.03.13 18:22
Оценка:
Пару раз встречал пример реализации паттерна Фабрика.
В обоих случаях код был примерно такой:

public class SomethingFactory {
   public Something create(String type) {
       if (type.equals("type1")) {
           return new Something_1Sub();
       } else if ("type2") {
       }
       // else etc.
   }
}


Почему в этих примерах type имеет тип String ?
Не лучше ли будет создать перечисление типа SomethingType ?
Тогда можно будет в create использовать оператор switch (до Java 1.7 со строками его использовать нельзя). И к тому же IDE будет выдавать подсказку о существующих значениях этого перечисления.
Или есть какие-то преимущества от использования String ?
Re: Реализация паттерна "Фабрика" на Java в книгах
От: cvetkov  
Дата: 01.03.13 19:10
Оценка: +1
Здравствуйте, pooo, Вы писали:

P>Пару раз встречал пример реализации паттерна Фабрика.

перестаньте читать эти книги.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Re: Реализация паттерна "Фабрика" на Java в книгах
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.03.13 20:15
Оценка:
P>Почему в этих примерах type имеет тип String ?

Такие примеры обычно показываются на примере deserialize-ации текстового представления, и поэтому тип представляется строкой.

P> Не лучше ли будет создать перечисление типа SomethingType ?


у enum-а плохо с расширяемостью. Если используется строка, то можно расширить фабрику, пронаследовавшись от нее и добавив поддержку доп. типов, если же используется enum, то расширить фабрику не получится.
Re: Реализация паттерна "Фабрика" на Java в книгах
От: andyag  
Дата: 01.03.13 20:33
Оценка: 2 (1) +1
Здравствуйте, pooo, Вы писали:

P>Пару раз встречал пример реализации паттерна Фабрика.


Странные книжки у вас. Это конечно фабрика, но какая-то она слишком специализированная. Возможно там рассматривался какой-то вполне конкретный пример, вы его пропустили, а на код посмотрели в отрыве от контекста. Вот такое:
public class PersonFactory {
  public Person makePerson() {
    return new Person();
  }
}

Это вполне себе фабрика. Фабрика не обязана уметь делать больше 1 типа объектов. Её метод make/create не обязан иметь параметры. Поэтому ваш вопрос про enum/String должен обсуждаться в контексте той задачи, которая там рассматривалась.
Re[2]: Реализация паттерна "Фабрика" на Java в книгах
От: pooo  
Дата: 01.03.13 21:13
Оценка:
Здравствуйте, andyag, Вы писали:

A>Здравствуйте, pooo, Вы писали:


P>>Пару раз встречал пример реализации паттерна Фабрика.


A>Странные книжки у вас. Это конечно фабрика, но какая-то она слишком специализированная. Возможно там рассматривался какой-то вполне конкретный пример, вы его пропустили, а на код посмотрели в отрыве от контекста.


Этот пример из книги по паттернам проектирования из серии HeadFirst (очень популярная книга, кстати).
Да, там рассматривался игрушечный пример — "Фабрика", создающая пиццу конкретного типа, по значению текстового аргумента, описывающего этот тип.
Вы говорите, что фабрика не обязана уметь создавать несколько разных типов объектов. Но тогда зачем нужна фабрика? разве умение создавать конкретный тип объекта по переданному фабрике описанию не единственно полезное свойство фабрики?

И еще. Почему я задал-то этот вопрос. Просто я подумал, что использование enum было бы удобнее (если использовать String — IDE не заметит возможную опечатку, а с enum при опечатке IDE укажет на нее; в добавок не нужно помнить все эти возможные аргументы типа String, при перечислениях IDE сама подскажет набор вариантов). Мне сперва подумалось, что использовали String чтобы например при добавлении нового типа (в данном примере это были объекты "Пицца") не нужно изменять перечисление возможных типов и соответственно перекомпилировать все классы, где это перечисление используется. Но потом понял, что перечисление типов используется там и только там, где используется Фабрика, (ведь перечисление нужно только при создании объектов), а Фабрику при добавлении новых типов объектов все равно придется изменять — соответственно, придется перекомпилировать зависимые классы (эти зависимые классы будут те же самые, что и классы, в которых используются перечисления).

Надеюсь, что не слишком тяжело выразился.
Re[2]: Реализация паттерна "Фабрика" на Java в книгах
От: pooo  
Дата: 01.03.13 21:15
Оценка:
Здравствуйте, DarkGray, Вы писали:


P>>Почему в этих примерах type имеет тип String ?


DG>Такие примеры обычно показываются на примере deserialize-ации текстового представления, и поэтому тип представляется строкой.


P>> Не лучше ли будет создать перечисление типа SomethingType ?


DG>у enum-а плохо с расширяемостью. Если используется строка, то можно расширить фабрику, пронаследовавшись от нее и добавив поддержку доп. типов, если же используется enum, то расширить фабрику не получится.


Простите, но я не догоняю что-то. Почему плохо? Разве нельзя в расширенном классе Фабрики сначала проверять на равенство аргумента одному из "новых" типов, а, если соответствие не найдено, то вызывать соответствующий метод суперкласса?
Re[3]: Реализация паттерна "Фабрика" на Java в книгах
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 01.03.13 23:51
Оценка: 2 (1)
P>Простите, но я не догоняю что-то. Почему плохо? Разве нельзя в расширенном классе Фабрики сначала проверять на равенство аргумента одному из "новых" типов, а, если соответствие не найдено, то вызывать соответствующий метод суперкласса?

как предлагается в enum, который описан в базовой сборке добавить перечисления под новые типы?
Re[3]: Реализация паттерна "Фабрика" на Java в книгах
От: andyag  
Дата: 02.03.13 13:16
Оценка: 2 (1)
Здравствуйте, pooo, Вы писали:

P>Здравствуйте, andyag, Вы писали:


A>>Здравствуйте, pooo, Вы писали:


P>>>Пару раз встречал пример реализации паттерна Фабрика.


A>>Странные книжки у вас. Это конечно фабрика, но какая-то она слишком специализированная. Возможно там рассматривался какой-то вполне конкретный пример, вы его пропустили, а на код посмотрели в отрыве от контекста.


P>Этот пример из книги по паттернам проектирования из серии HeadFirst (очень популярная книга, кстати).

P>Да, там рассматривался игрушечный пример — "Фабрика", создающая пиццу конкретного типа, по значению текстового аргумента, описывающего этот тип.
P>Вы говорите, что фабрика не обязана уметь создавать несколько разных типов объектов. Но тогда зачем нужна фабрика? разве умение создавать конкретный тип объекта по переданному фабрике описанию не единственно полезное свойство фабрики?

Одна из ценностей "правильного" дизайна — это разделение ответственностей (погуглите например SOLID). Разделение ответственностей достигается путём делегирования. Делегировать можно всё что угодно, в том числе и конструирование каких-то новых объектов. Паттерн проектирования Фабрика описывает именно вот этот конкретный случай: какой-то кусок кода хочет сконструировать объект с некоторомы интерфейсом, но при этом не владеет достаточной информацией о том, как этот объект сконструировать.

P>И еще. Почему я задал-то этот вопрос. Просто я подумал, что использование enum было бы удобнее (если использовать String — IDE не заметит возможную опечатку, а с enum при опечатке IDE укажет на нее; в добавок не нужно помнить все эти возможные аргументы типа String, при перечислениях IDE сама подскажет набор вариантов). Мне сперва подумалось, что использовали String чтобы например при добавлении нового типа (в данном примере это были объекты "Пицца") не нужно изменять перечисление возможных типов и соответственно перекомпилировать все классы, где это перечисление используется. Но потом понял, что перечисление типов используется там и только там, где используется Фабрика, (ведь перечисление нужно только при создании объектов), а Фабрику при добавлении новых типов объектов все равно придется изменять — соответственно, придется перекомпилировать зависимые классы (эти зависимые классы будут те же самые, что и классы, в которых используются перечисления).


Пока нет конкретной задачи, обсуждать этот вопрос бессмысленно С точки зрения бизнеса, пиццу очень часто делают по спецификации: "томатная, с колбасой и ананасами". Варианты типа "Пепперони" имеют мало смысла, т.к. её можно сделать и с помидорами, и без них, при этом она всё ещё будет Пепперони.
Re[3]: Реализация паттерна "Фабрика" на Java в книгах
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.03.13 07:20
Оценка: 1 (1)
Здравствуйте, pooo, Вы писали:

P>Вы говорите, что фабрика не обязана уметь создавать несколько разных типов объектов. Но тогда зачем нужна фабрика? разве умение создавать конкретный тип объекта по переданному фабрике описанию не единственно полезное свойство фабрики?

Нет. Единственное полезное свойство фабрики — умение создавать тип, заранее неизвестный (или с заранее неизвестными параметрами) для вызывающего.
Раньше я хардкодил вызов конструктора:
var person = new Person();

Теперь я делегирую это фабрике:
var person = _personFactory.makePerson();

Во-первых, уже сейчас я могу поменять определение метода makePerson() в том классе, экземпляр которого лежит в _personFactory. И у меня везде согласованно поменяется способ порождения Person.
Во-вторых, я в эту _personFactory могу положить ссылку на любого потомка PersonFactory, например:

public class ManagerFactory: PersonFactory
{
  public override Person makePerson()
  {
    return new Manager();
  }
}


А в вашей книжке в фабрику запихивается сразу две задачи — порождение экземпляров класса и диспетчеризация по запрошенному типу.
Более компетентный пример выглядел бы как-то так:


var something = _somethingTypeRegistry.GetFactory(/*string*/ type).CreateSomething();
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.