4

Smalltalk 中是否使用了工厂方法,如果是,应该如何编写一种方法,而不是在 Java 中使用工厂方法?谢谢。

4

2 回答 2

11

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

Pizza
  PepperoniPizza
  CheesePizza
  ...

我们想在不知道它的类名的情况下实例化一个披萨子类。例如:

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

回答披萨的正确子类,并填写其大小。

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

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

无需维护中央 switch 语句。只是对象!

于 2010-06-25T22:29:17.213 回答
0

首先,在 Smalltalk 中,您已经命名了构造函数。事实上,类是对象,而“构造函数”只是在类上定义的、碰巧返回新实例的方法。其他语言中工厂方法的许多用途都可以通过这种方式涵盖。

例如

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

它通过名称获取事物,并且仅在具有该名称的事物尚不存在时才创建新事物。

于 2010-07-01T01:32:28.600 回答