装饰图案

装饰器模式为对象添加行为,而不会影响同一类的其他对象。装饰器模式是创建子类的有用替代方法。

为每个装饰器创建一个模块。这种方法比继承更灵活,因为你可以在更多组合中混合和匹配职责。此外,由于透明度允许装饰器以递归方式嵌套,因此它允许无限数量的责任。

假设 Pizza 类有一个返回 300 的成本方法:

class Pizza
  def cost
    300
  end
end

代表披萨加上一层奶酪爆裂,成本上升 50 倍。最简单的方法是创建一个 PizzaWithCheese 子类,在成本方法中返回 350。

class PizzaWithCheese < Pizza
  def cost
    350
  end
end

接下来,我们需要代表一个大披萨,它可以增加普通披萨的成本。我们可以使用 Pizza 的 LargePizza 子类来表示这一点。

class LargePizza < Pizza
  def cost
    400
  end
end

我们还可以使用 ExtraLargePizza,为 LargePizza 增加 15 美元。如果我们考虑这些披萨类型可以配上奶酪,我们需要添加 LargePizzaWithChese 和 ExtraLargePizzaWithCheese 子类。我们最终总共有 6 个类。

要简化方法,请使用模块向 Pizza 类动态添加行为:

模块+扩展+超级装饰: - >

class Pizza
  def cost
    300
  end
end

module CheesePizza
  def cost
    super + 50
  end
end

module LargePizza
  def cost
    super + 100
  end
end

pizza = Pizza.new         #=> cost = 300
pizza.extend(CheesePizza) #=> cost = 350
pizza.extend(LargePizza)  #=> cost = 450
pizza.cost                #=> cost = 450