MST
星途 面试题库

面试题:Ruby中策略模式的应用案例解析

请描述在Ruby中如何实现策略模式,并给出一个简单的应用案例,说明在该案例中策略模式如何提高代码的可维护性和扩展性。
27.1万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试

策略模式在Ruby中的实现

  1. 定义策略接口(通常是一个模块): 策略模式首先需要定义一个通用的接口,不同的策略类将实现这个接口。在Ruby中,可以使用模块来定义这个接口。
module DiscountStrategy
  def calculate_discount(price)
    raise NotImplementedError, "Subclasses must implement calculate_discount method"
  end
end
  1. 创建具体策略类: 具体策略类实现上述定义的接口。
class PercentageDiscount < Struct.new(:percentage)
  include DiscountStrategy
  def calculate_discount(price)
    price * percentage / 100.0
  end
end

class FixedAmountDiscount < Struct.new(:amount)
  include DiscountStrategy
  def calculate_discount(price)
    [amount, price].min
  end
end
  1. 使用策略模式的上下文类: 上下文类持有一个策略对象,并通过调用策略对象的方法来执行相应的策略。
class ShoppingCart
  def initialize(discount_strategy)
    @discount_strategy = discount_strategy
    @items = []
  end

  def add_item(price, quantity)
    @items << { price: price, quantity: quantity }
  end

  def total_price
    @items.sum { |item| item[:price] * item[:quantity] }
  end

  def discounted_price
    total = total_price
    total - @discount_strategy.calculate_discount(total)
  end
end

应用案例

假设我们正在开发一个电商购物车系统,需要根据不同的促销活动计算商品的折扣价格。

  1. 提高代码可维护性
    • 每个折扣计算逻辑(策略)都封装在单独的类中。例如,如果需要修改百分比折扣的计算逻辑,只需要修改PercentageDiscount类中的calculate_discount方法,而不会影响到其他折扣策略类或购物车的其他部分代码。
    • 如果添加新的折扣类型,比如“满减折扣”,只需要创建一个新的策略类,实现DiscountStrategy接口,而不需要修改现有的大量代码。这使得代码结构清晰,易于维护。
  2. 提高代码扩展性
    • 当业务需求发生变化,需要增加新的折扣策略时,扩展性非常好。例如,我们可以轻松添加一个“买一送一”的折扣策略,只需要创建一个新的策略类并实现DiscountStrategy接口。
    • 购物车类ShoppingCart不需要关心具体的折扣计算逻辑,只需要通过注入的策略对象来调用相应的方法。这样,我们可以在运行时根据不同的促销活动,灵活地更换折扣策略,而不需要修改购物车类的核心代码。

使用示例

# 使用百分比折扣策略
percentage_discount = PercentageDiscount.new(10)
cart1 = ShoppingCart.new(percentage_discount)
cart1.add_item(100, 2)
cart1.add_item(50, 3)
puts "Cart1 discounted price: #{cart1.discounted_price}"

# 使用固定金额折扣策略
fixed_amount_discount = FixedAmountDiscount.new(50)
cart2 = ShoppingCart.new(fixed_amount_discount)
cart2.add_item(100, 2)
cart2.add_item(50, 3)
puts "Cart2 discounted price: #{cart2.discounted_price}"

在这个示例中,通过策略模式,我们将折扣计算逻辑从购物车的核心业务逻辑中分离出来,使得代码更易于维护和扩展。