Smalltalk эквивалент фабричного метода?

Используются ли фабричные методы в Smalltalk, и если да, то как их написать, а не как, например, в Java? Спасибо.


person Everard    schedule 25.06.2010    source источник
comment
У меня нет ответа, но я нашел это на slideshare.net с несколько слайдов о Фабрике, может поможет.   -  person Serty Oan    schedule 26.06.2010


Ответы (2)


В фабричном шаблоне мы создаем экземпляр некоторого подкласса, не называя его. Рассмотрим фабрику пиццы и иерархию:

Pizza
  PepperoniPizza
  CheesePizza
  ...

Мы хотели бы создать экземпляр подкласса пиццы, не зная его имени. Например:

  pizza := Pizza flavor: 'cheese' size: 12 inches

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

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

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

Pizza class>>flavor: aString size: anInteger
  matchingClass := self subclasses detect: [:first | first matching: aString].
  ^matchingClass new size: anInteger.

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

CheesePizza class>>matching: aString
  ^aString = 'cheese'
PepperoniPizza class>>matching: aString
  ^aString = 'pepperoni'

Нет оператора центрального переключателя, который нужно поддерживать. Просто объекты!

person Alan Wostenberg    schedule 25.06.2010
comment
Теперь в Java или C++ можно было бы, вероятно, сделать большой оператор «переключатель» для сравнения разных имен строк. Ваш пример Smalltalk с «сопоставлением» довольно эквивалентен использованию отражения Java и динамической загрузки классов, что я и делаю в Java во всех, кроме самых тривиальных случаях фабрики. Я читал раньше некоторые вещи о том, что если у вас есть большие операторы switch, вы делаете OO неправильно. Жаль, что я мог бы найти ссылку сейчас. - person Stephen P; 26.06.2010

Прежде всего, в Smalltalk у вас есть именованные конструкторы. На самом деле классы — это объекты, а «конструкторы» — это просто методы, определенные в классе, которые возвращают новые экземпляры. Таким образом можно охватить многие случаи использования фабричных методов в других языках.

Например

Thing class >> withName: aString
    ^ dictionaryOfAllThings 
        at: aString 
        ifAbsentPut: (self new name: aString; yourself)

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

person akuhn    schedule 01.07.2010