面试题答案
一键面试策略模式在Ruby中的实现
- 定义策略接口(通常是一个模块): 策略模式首先需要定义一个通用的接口,不同的策略类将实现这个接口。在Ruby中,可以使用模块来定义这个接口。
module DiscountStrategy
def calculate_discount(price)
raise NotImplementedError, "Subclasses must implement calculate_discount method"
end
end
- 创建具体策略类: 具体策略类实现上述定义的接口。
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
- 使用策略模式的上下文类: 上下文类持有一个策略对象,并通过调用策略对象的方法来执行相应的策略。
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
应用案例
假设我们正在开发一个电商购物车系统,需要根据不同的促销活动计算商品的折扣价格。
- 提高代码可维护性:
- 每个折扣计算逻辑(策略)都封装在单独的类中。例如,如果需要修改百分比折扣的计算逻辑,只需要修改
PercentageDiscount
类中的calculate_discount
方法,而不会影响到其他折扣策略类或购物车的其他部分代码。 - 如果添加新的折扣类型,比如“满减折扣”,只需要创建一个新的策略类,实现
DiscountStrategy
接口,而不需要修改现有的大量代码。这使得代码结构清晰,易于维护。
- 每个折扣计算逻辑(策略)都封装在单独的类中。例如,如果需要修改百分比折扣的计算逻辑,只需要修改
- 提高代码扩展性:
- 当业务需求发生变化,需要增加新的折扣策略时,扩展性非常好。例如,我们可以轻松添加一个“买一送一”的折扣策略,只需要创建一个新的策略类并实现
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}"
在这个示例中,通过策略模式,我们将折扣计算逻辑从购物车的核心业务逻辑中分离出来,使得代码更易于维护和扩展。