如何在PHP中使用Strategy pattern实现带特殊日期变体的每日消息功能
基于策略模式的每日消息功能PHP实现
核心设计逻辑
- 定义统一的消息策略接口,所有消息生成逻辑都遵循该接口规范,方便后续扩展新的特殊日期策略
- 不同场景的消息生成逻辑独立为单独的策略类,互不干扰
- 上下文类负责策略的调度,可自动根据当前日期匹配对应策略,也支持手动指定策略
完整实现代码
1. 定义消息策略接口
<?php interface MessageStrategyInterface { /** * 加工生成最终展示的消息 * @param string $baseDailyMessage 当日基础消息内容 * @return string */ public function generate(string $baseDailyMessage): string; }
2. 实现普通每日消息策略
<?php class DefaultMessageStrategy implements MessageStrategyInterface { public function generate(string $baseDailyMessage): string { // 普通日期直接返回原始消息 return $baseDailyMessage; } }
3. 实现圣诞节特殊消息策略
<?php class ChristmasMessageStrategy implements MessageStrategyInterface { public function generate(string $baseDailyMessage): string { // 圣诞节添加专属前缀 return "圣诞快乐:" . $baseDailyMessage; } }
4. 实现策略调度上下文类
<?php class DailyMessageContext { protected MessageStrategyInterface $strategy; /** * 支持手动传入指定策略 * @param MessageStrategyInterface $strategy */ public function __construct(MessageStrategyInterface $strategy) { $this->strategy = $strategy; } /** * 自动根据当前日期匹配对应策略 * @return self */ public static function createFromCurrentDate(): self { $currentDate = new DateTime(); $month = (int)$currentDate->format('m'); $day = (int)$currentDate->format('d'); // 匹配圣诞节:12月25日 if ($month === 12 && $day === 25) { return new self(new ChristmasMessageStrategy()); } // 默认普通日期策略 return new self(new DefaultMessageStrategy()); } /** * 执行策略生成最终消息 * @param string $baseDailyMessage * @return string */ public function getFinalMessage(string $baseDailyMessage): string { return $this->strategy->generate($baseDailyMessage); } }
使用示例
<?php // 模拟从配置/数据库获取的当日基础消息 $todayBaseMessage = "今日限时福利:所有商品满200减50"; // 自动根据日期选择策略 $messageContext = DailyMessageContext::createFromCurrentDate(); echo $messageContext->getFinalMessage($todayBaseMessage); // 输出结果: // 普通日期:今日限时福利:所有商品满200减50 // 12月25日:圣诞快乐:今日限时福利:所有商品满200减50
扩展说明
如果需要新增其他特殊日期的消息规则,只需要新增实现MessageStrategyInterface的策略类,然后在DailyMessageContext::createFromCurrentDate()方法中添加对应日期判断逻辑即可,不需要修改原有已上线的消息生成逻辑,符合开闭原则。
内容的提问来源于stack exchange,提问作者Rafael Melo
相关产品推荐
相关产品推荐

