什么是 Ruby 工厂方法?

问题描述 投票:0回答:3

我理解工厂方法是一种类方法,它利用

self
关键字并实例化它自己的类的对象。我不明白这有什么用处,或者它如何扩展
initialize
方法的功能。

我正在开发一个创建命令行地址簿的项目,该项目要求我在 Person 类上使用工厂模式,以便我可以创建具有不同属性的受训者或讲师(子类)。

ruby factory-pattern factory-method
3个回答
23
投票

工厂类是一种使用单一工厂方法来生成各种对象的干净方法。 它需要一个参数,这个参数告诉方法要创建哪种对象。例如,生成

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

我还写了一篇关于该主题的更详细的博客文章:工厂模式


4
投票

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

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

trainee = Person.new true

instructor = Person.new false

真假分支创建讲师或实习生。

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

trainee = Person.create_trainee
instructor = Person.create_instructor

1
投票

为什么要费心使用工厂方法?

(A) 为了简化事情:

  • 创建对象可能很复杂,并且

  • 您可能需要多次执行此操作。

  • 很难记住:

    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.

(B) 允许覆盖/存根

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

© www.soinside.com 2019 - 2024. All rights reserved.