什么是 Ruby 工厂方法?

What is a Ruby factory method?

我知道工厂方法是一种 class 方法,它利用 self 关键字并实例化它自己的对象 class。我不明白这有什么用或者它如何扩展 initialize 方法的功能。

我正在开发一个创建命令行地址簿的项目,它要求我在人员 class 上使用工厂模式,以便我可以创建实习生或讲师(subclass es) 具有不同的属性。

工厂方法模式至少允许您为本来可能是复杂或不透明的构造函数提供一个富有表现力的名称。例如,如果你有一个带有一堆参数的构造函数,调用者可能不清楚为什么,拥有一个或多个命名的工厂方法可能会隐藏对象创建的复杂性,并使你的代码更能表达实际的内容进行中。

所以在你的情况下,糟糕的设计可能是:

trainee = Person.new true

instructor = Person.new false

创建讲师或受训者的真假分支。

这可以通过使用工厂方法来阐明正在发生的事情来改进:

trainee = Person.create_trainee
instructor = Person.create_instructor

工厂class 是一种使用单个工厂方法生成各种对象的简洁方法。 它有一个参数,这个参数告诉方法要创建哪种对象。例如生成 EmployeeBoss,具体取决于传入的符号:

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

我还写了一篇关于该主题的更详细的博客 post:The Factory Pattern

为什么要使用工厂方法?

(A) 简化事情:

创建对象可能很复杂,您可能需要多次执行此操作。我们是人:很难记住事情。为什么不让我们自己轻松一点?

driver = Person.new
engine = RollsRoyce.new
engine.turbo_charged = true
engine.max_rpm = 100000    
car.new
car.driver = driver
car.engine = engine`

(B) 允许覆盖/存根

如果您正在编写可测试的代码,您可能想要创建自己的专用 'crash dummy vehicle' 以便您可以测试碰撞等。如果您有工厂方法/对象,那么您可以轻松地做到这一点。这是一个有点高级的主题 - google“创建接缝”或“依赖项注入”了解更多信息。