Smalltalk中是否使用工厂方法,如果使用,如何编写工厂方法,与Java等其他语言有何不同? 谢谢。
Smalltalk中是否使用工厂方法,如果使用,如何编写工厂方法,与Java等其他语言有何不同? 谢谢。
在工厂模式中,我们实例化某个子类而不给它命名。考虑一个披萨工厂和层次结构:
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'
没有需要维护的中央开关语句。只需使用对象!
Thing class >> withName: aString
^ dictionaryOfAllThings
at: aString
ifAbsentPut: (self new name: aString; yourself)
根据名称获取一个对象,仅在该名称的对象不存在时创建新对象。