You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby策略模式优化:避免无关方法继承的DRY实现问询

解决Ruby策略模式中的不必要方法继承问题

Great question—this is a classic case where overusing inheritance can lead to bloated base classes and unnecessary method exposure, which is definitely a code smell we want to avoid. Let’s walk through a few clean, Ruby-idiomatic solutions tailored to your scenario:

方案1:使用模块(Module)实现组合式复用

Ruby’s modules are perfect for extracting shared behavior that only applies to a subset of your strategy classes. Instead of polluting the base class with add_hot_sauce, we’ll wrap this method in a module and "mix it in" only where it’s needed.

# 提取共享的加辣酱行为到模块
module HotSauceable
  def add_hot_sauce
    # 这里是你的具体实现逻辑
    puts "Drizzling spicy hot sauce!"
  end
end

# 基类只保留所有策略共有的核心方法
class FoodStrategy
  def prepare_food
    raise NotImplementedError, "Subclasses must implement #prepare_food"
  end
end

# 需要加辣酱的策略混入模块
class FoodStrategies::Taco < FoodStrategy
  include HotSauceable

  def prepare_food
    add_hot_sauce
    # 其他制作taco的逻辑
    puts "Assembling crunchy taco!"
  end
end

class FoodStrategies::Burrito < FoodStrategy
  include HotSauceable

  def prepare_food
    add_hot_sauce
    # 其他制作burrito的逻辑
    puts "Wrapping hearty burrito!"
  end
end

# 不需要辣酱的策略直接继承基类,无多余方法
class FoodStrategies::Cereal < FoodStrategy
  def prepare_food
    # 制作麦片的逻辑
    puts "Pouring milk over cereal!"
  end
end

优点:

  • 遵循组合优于继承的原则,避免了不必要的继承层次
  • 每个策略类只包含它实际需要的行为,符合单一职责原则
  • 模块可以轻松复用在其他需要加辣酱的类中,扩展性强

方案2:拆分基类形成层次结构

If add_hot_sauce is part of a larger set of shared behaviors for your spicy food strategies, you can split your base class into a two-level hierarchy:

# 最基础的基类,包含所有策略通用的方法
class BaseFoodStrategy
  def prepare_food
    raise NotImplementedError, "Subclasses must implement #prepare_food"
  end
end

# 专门为需要加辣酱的策略创建子类
class SpicyFoodStrategy < BaseFoodStrategy
  def add_hot_sauce
    puts "Drizzling spicy hot sauce!"
  end
end

# 辣味策略继承自SpicyFoodStrategy
class FoodStrategies::Taco < SpicyFoodStrategy
  def prepare_food
    add_hot_sauce
    puts "Assembling crunchy taco!"
  end
end

class FoodStrategies::Burrito < SpicyFoodStrategy
  def prepare_food
    add_hot_sauce
    puts "Wrapping hearty burrito!"
  end
end

# 非辣味策略直接继承BaseFoodStrategy
class FoodStrategies::Cereal < BaseFoodStrategy
  def prepare_food
    puts "Pouring milk over cereal!"
  end
end

优点:

  • 清晰划分了策略的层次,适合有多个共享行为的场景
  • 保留了继承的语义,让代码意图更明确
  • 避免了无用方法的跨类继承

注意: 这个方案更适合当你有一组相关的共享方法(不止add_hot_sauce),否则模块方案会更轻量灵活。

为什么不把add_hot_sauce放在基类?

Putting add_hot_sauce in the base class would force FoodStrategies::Cereal to inherit a method it never uses. This violates the Interface Segregation Principle (clients shouldn’t depend on interfaces they don’t need) and creates a "fat base class" that becomes harder to maintain as your strategy set grows.

内容的提问来源于stack exchange,提问作者Argus9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:57:11