2010-06-25 60 views
4

Smalltalk中是否使用了工厂方法,如果是的话,那么应该如何编写一个,而不是它们在Java中的方式? 谢谢。Smalltalk相当于一种工厂方法?

+0

我还没有找到答案,但在slideshare.net上找到[this](http://www.slideshare.net/speludner/layers-of-smalltalk-application)以及一些关于Factory的幻灯片,可能会有所帮助。 – 2010-06-25 20:22:49

回答

11

在一个工厂模式中,我们实例化了一些没有命名的子类。考虑一个比萨工厂和等级:

Pizza 
    PepperoniPizza 
    CheesePizza 
    ... 

我们希望实例化一个披萨子类而不知道它是类名。例如:

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

回答比萨的右子类,它填补了它的大小

现在在Java或C++一个可能会做一个大的“开关”的语句在不同的字符串名称比较。每次我们添加一个新的Pizza的子类时,我们都需要记住添加到主switch语句中。典型示例请参见Wikipedia article

在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' 

没有中央的开关语句来维护。只是物件!

+0

“现在在Java或C++中,可能会做一个大型的”switch“语句来比较不同的字符串名称”---您的Smalltalk示例与“匹配”相当于使用Java反射和动态类加载,这就是除了工厂最微不足道的情况之外,我都是用Java来做的。我之前已经读过一些“如果你有很大的开关语句你做错了”的效果。希望我现在能找到一个参考。 – 2010-06-25 22:38:31

0

首先,在Smalltalk中,您已命名构造函数。事实上,类是对象,“构造函数”只是在类中定义的方法,它们恰好返回新实例。其他语言的工厂方法的许多用途可以用这种方式来涵盖。

例如

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

它通过名字来取得的东西,只有当与该名称的东西不存在创建一个新的东西。