Smalltalk中的工厂方法等价物是什么?

4

Smalltalk中是否使用工厂方法,如果使用,如何编写工厂方法,与Java等其他语言有何不同? 谢谢。


我没有答案,但在slideshare.net上找到了这个链接,其中有一些关于工厂的幻灯片,希望能有所帮助。 - Serty Oan
2个回答

11

在工厂模式中,我们实例化某个子类而不给它命名。考虑一个披萨工厂和层次结构:

Pizza
  PepperoniPizza
  CheesePizza
  ...
我们希望能够实例化一个比萨子类,而不必知道它的类名。例如:
  pizza := Pizza flavor: 'cheese' size: 12 inches

返回正确类型的比萨子类,并填写其大小。

现在在Java或C ++中,人们可能会编写大型“switch”语句来比较不同的字符串名称。每次添加新的Pizza子类时,我们都需要记住在主switch语句中添加。有关典型示例,请参见维基百科文章

但在Smalltalk中不是这样,因为类是一等对象,所以我们可以迭代类层次结构,询问每个子类是否匹配。例如:

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

每当我们实现一个新的pizza子类时,我们会实现一个方法来执行工厂匹配:

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

没有需要维护的中央开关语句。只需使用对象!


现在在Java或C++中,人们可能会使用大型“switch”语句来比较不同的字符串名称。你的Smalltalk示例与“匹配”相当于在Java中使用反射和动态类加载,在除了最简单的工厂情况下我都这样做。我以前读过一些关于“如果你有大型switch语句,那么你的OO设计是错误的”的说法。但愿我现在能找到一个参考。 - Stephen P

0
首先,在Smalltalk中,你有命名构造函数。实际上,类是对象,“构造函数”只是在类上定义的方法,恰好返回新实例。许多其他语言中工厂方法的用途可以通过这种方式来覆盖。
例如:
Thing class >> withName: aString
    ^ dictionaryOfAllThings 
        at: aString 
        ifAbsentPut: (self new name: aString; yourself)

根据名称获取一个对象,仅在该名称的对象不存在时创建新对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接