我理解工厂方法是一种类方法,它利用
self
关键字并实例化它自己的类的对象。我不明白这有什么用处,或者它如何扩展 initialize
方法的功能。
我正在开发一个创建命令行地址簿的项目,该项目要求我在 Person 类上使用工厂模式,以便我可以创建具有不同属性的受训者或讲师(子类)。
工厂类是一种使用单一工厂方法来生成各种对象的干净方法。 它需要一个参数,这个参数告诉方法要创建哪种对象。例如,生成
Employee
或 Boss
,具体取决于传入的符号:
class Person
def initialize(attributes)
end
end
class Boss
def initialize(attributes)
end
end
class Employee
def initialize(attributes)
end
end
class PersonFactory
TYPES = {
employee: Employee,
boss: Boss
}
def self.for(type, attributes)
(TYPES[type] || Person).new(attributes)
end
end
然后:
employee = PersonFactory.for(:employee, name: 'Danny')
boss = PersonFactory.for(:boss, name: 'Danny')
person = PersonFactory.for(:foo, name: 'Danny')
我还写了一篇关于该主题的更详细的博客文章:工厂模式
工厂方法模式至少允许您为复杂或不透明的构造函数提供一个富有表现力的名称。例如,如果您有一个带有一堆参数的构造函数,那么调用者可能不清楚为什么使用一个或多个命名工厂方法可能会隐藏对象创建的复杂性,并使您的代码更能表达实际内容。正在进行中。
所以在你的情况下,糟糕的设计可能是:
trainee = Person.new true
或
instructor = Person.new false
真假分支创建讲师或实习生。
可以通过使用工厂方法来澄清正在发生的事情来改进:
trainee = Person.create_trainee
instructor = Person.create_instructor
创建对象可能很复杂,并且
您可能需要多次执行此操作。
很难记住:
driver = Person.new
engine = Brrrm.new
engine.turbo_charged = true
engine.max_rpm = 100000
car = Porsche.new
car.driver = driver
car.engine = engine
# ugh - too much work!
ben = PersonFactory.create("ben")
car = PorscheFactory.create(ben)
# two lines, and nothing more
# and you get the following for free:
car.turbo_charged # => true
car.engine # => brrrm
car.driver # => ben_koshy
car.driver.personality # => :excellent_dude
# you can mix and match default values with options.
# generally speaking you want to inject as much as you can
# i.e. inverting dependencies. I make these illustrates to
# explain a concept, not as an example of great coding.
如果您正在编写可测试的代码,您可能想要创建自己的专用“碰撞虚拟车辆”,以便可以测试碰撞等。如果您有工厂方法/对象,那么您可以轻松地做到这一点。这是一个有点高级的主题 - 谷歌“创建接缝”或“依赖注入”以获取更多信息。