HelloWorld 策略模式教程

2026年6月30日 作者:admin

策略模式(Strategy Pattern)是一种把可变行为封装为独立策略对象的设计方法。它通过定义统一接口,把算法从使用它的类中剥离出来,使得在运行时可以替换、组合或扩展这些行为。以 HelloWorld 为例,你可以把“如何输出”做成不同策略(纯文本、带时间戳、国际化前缀等),上下文只负责调用策略,从而减少条件分支、提高测试性与可维护性。

HelloWorld 策略模式教程

什么是策略模式(用最简单的话说)

想象你有一个会“说话”的小模块,它可以用不同方式说“Hello World”:普通朗读、打印带时间戳、或者替换成其他语言。策略模式就是把这些“说话方式”做成可插拔的零件。上下文(说话者)不关心具体怎么说,只调用“说话零件”的接口。这样新增或切换说话方式就像换电池一样简单。

核心要点(一句话)

  • 分离变化:把会变的算法或行为封装为策略类。
  • 运行时可替换:上下文在运行时持有策略并委托执行。
  • 接口统一:所有策略都实现同一个接口,易于扩展与测试。

策略模式的组成(术语对应的角色)

角色 职责
Strategy(策略接口) 定义一组可互换的操作抽象,如 say()
ConcreteStrategy(具体策略) 实现策略接口,提供具体算法或行为
Context(上下文) 持有一个 Strategy 引用,调用策略方法,不包含算法逻辑

HelloWorld 实战教程(逐步)

我们用费曼式分解法来讲,先把问题拆成最简单的块,然后逐步复用和组合。目标:把“打印 Hello World”变成可插拔的行为。

步骤 1:识别变化点

  • 输出内容(Hello World、Bonjour le monde 等)
  • 输出风格(纯文本、加前缀、带时间戳、写入文件等)
  • 可能的输入参数(语言、格式化方式)

步骤 2:定义策略接口

接口通常非常小,只包含执行方法。例如:

interface HelloStrategy {
    void say();
}

步骤 3:实现几个具体策略

举几个常用例子:

// 普通输出
class PlainHello implements HelloStrategy {
    void say() { System.out.println("Hello World"); }
}
// 带时间戳
class TimestampHello implements HelloStrategy {
    void say() { System.out.println(System.currentTimeMillis() + " Hello World"); }
}
// 国际化示例
class I18nHello implements HelloStrategy {
    private String lang;
    I18nHello(String lang) { this.lang = lang; }
    void say() {
        switch(lang) {
            case "fr": System.out.println("Bonjour le monde"); break;
            case "zh": System.out.println("你好,世界"); break;
            default: System.out.println("Hello World");
        }
    }
}

步骤 4:实现上下文

上下文只持有一个策略引用,提供设置策略的方法与执行方法:

class HelloContext {
    private HelloStrategy strategy;
    HelloContext(HelloStrategy s) { this.strategy = s; }
    void setStrategy(HelloStrategy s) { this.strategy = s; }
    void execute() { strategy.say(); }
}

步骤 5:运行时切换

这样你可以按需切换:

HelloContext ctx = new HelloContext(new PlainHello());
ctx.execute();             // Hello World
ctx.setStrategy(new TimestampHello());
ctx.execute();             // 162... Hello World
ctx.setStrategy(new I18nHello("zh"));
ctx.execute();             // 你好,世界

多语言实现(快速示例)

下面给出 Python 和 JavaScript 的简单实现,对比差异:

Python 版本

from abc import ABC, abstractmethod
class HelloStrategy(ABC):
    @abstractmethod
    def say(self): pass

class PlainHello(HelloStrategy):
    def say(self):
        print("Hello World")

class TimestampHello(HelloStrategy):
    def say(self):
        import time
        print(f"{int(time.time())} Hello World")

class HelloContext:
    def __init__(self, strategy: HelloStrategy):
        self._strategy = strategy
    def set_strategy(self, s: HelloStrategy):
        self._strategy = s
    def execute(self):
        self._strategy.say()

JavaScript(ES6)

class PlainHello {
  say() { console.log("Hello World"); }
}
class TimestampHello {
  say() { console.log(Date.now(), "Hello World"); }
}
class HelloContext {
  constructor(strategy) { this.strategy = strategy; }
  setStrategy(s) { this.strategy = s; }
  execute() { this.strategy.say(); }
}

为什么用策略模式?好处与直观例子

  • 减少条件分支:把 if/else 或 switch 拆成多个类,各自负责一种行为。
  • 提高可测试性:每个策略都可以独立单元测试。
  • 开闭原则:新增策略不需要修改上下文。
  • 运行时灵活性:可以在程序运行期间替换策略,实现动态行为调整。

常见误区与何时不该用

  • 不要为了避免少量条件而过度拆分:如果只有两三个简单分支,函数内 switch 可能更直观。
  • 策略数量过多会增加类/对象管理复杂度,尤其在不支持依赖注入的小项目里。
  • 如果策略间有大量共享状态,考虑组合(composition)或状态模式(State)代替。

与相近模式的对比

模式 区别
Strategy 把算法封装为独立类,客户端或上下文选择并使用
State 对象内部状态驱动行为切换,关注“状态”而不是“算法”
Template Method 继承方式复用流程,子类重写步骤;策略是组合优先
Command 封装请求为对象,侧重调用时序与撤销;策略侧重替换算法

测试与实务建议

  • 对每个策略写独立单元测试,验证边界输入与异常处理。
  • 如果策略需要配置,尽量使用不可变参数或构造注入,避免全局状态。
  • 在大型系统中配合依赖注入框架(如 Spring、Guice)实现策略注册与切换。
  • 给策略命名要语义化:AvoidStrategy、CompactTimestampStrategy 之类笨拙名称会增加理解成本。

实际演练建议(小任务,练习掌握)

  • 任务 1:实现五种 Hello 输出策略(Plain、Timestamp、UpperCase、FileWriter、i18n),并编写测试覆盖率到 90%。
  • 任务 2:使用依赖注入自动选择策略:根据运行时配置加载不同策略实现。
  • 任务 3:对现有包含大量 switch 的模块进行重构,用策略替代分支,评估代码行数和出错率变化。

实践中常见的扩展场景

策略模式并非只能替换输出行为,它对以下场景也非常有用:

  • 排序策略(多种排序算法切换)
  • 压缩/加密策略(不同算法按需替换)
  • 支付方式、折扣规则、路由策略等业务规则引擎

小贴士(写给实战的你)

  • 先写最简单的策略:从 Plain 实现开始,再抽象通用接口。
  • 保持策略无副作用:尽量让策略方法只做一件事,便于重用与并发执行。
  • 如果策略很小,可以用函数式风格代替类(很多语言支持函数作为一等公民)。

就像把一盒调色盘分成单色颜料一样,策略模式让你把“如何做”拆成可拼凑的模块。拿 HelloWorld 练练手,能迅速看到效果,然后慢慢把更复杂的业务逻辑也拆出来,你会发现代码变得更轻、更易测、也更好改——这是动手实践后才会体会到的小快乐。

相关文章

了解更多相关内容

HelloWorld智能翻译软件 与世界各地高效连接