Design Pattern: Strategy 模式

简介:

  学习是分享和合作式的!

转载请注明出处:http://blog.csdn.net/wdzxl198/article/details/9306775

文章摘自: http://www.riabook.cn/doc/designpattern/

考虑您要设计一个更换各种符号的工具类TextCharChange,您是否会采用这样的方式:

   1: public void replace() {
   2:    switch(getChangeType()) {
   3:       case RN_TYPE:  
   4:                 replaceRN();
   5:                 break;
   6:       case N_TYPE: 
   7:                 replaceN();
   8:                 break;
   9:       case OTHER_TYPE: 
  10:                 replaceOTHER():
  11:                 break;
  12:       ...
  13:    }
  14: }

这么作的缺点是,日后您要增加更换符号的策略时,会有几个地方需要修改:增加TYPE常数、增加TextCharChange中的 replaceXXX()方法、增加 replace()方法中的switch case判断。
像这种策略采用的情况,可以将策略加以封装为一个物件,而不是将策略写死在某个类中,如此一来,策略可以独立于客户端,随时增加变化、增加或减少策略,即使是修改每个策略的内容,也不会对客户端程式造成影响。
来举个最简单的例子,首先要知道Windows与Linux的文字档案换行符号是不同的,Windows是 /r/n ,而Linux是 /n,今天您要设计一个文字编辑器,在适当的时候,您必须要能随时转换这两种符号,如果不采用上面的策略采用流程的话,要如何设计:

  • TextStrategy.java
   1: public abstract class TextStrategy { 
   2:     protected String text;
   3:  
   4:     public TextStrategy(String text) { 
   5:         this.text = text; 
   6:     }
   7:  
   8:     public abstract String replace(); 
   9: }  
  • LinuxStrategy.java
 
 
   1: public class LinuxStrategy extends TextStrategy { 
   2:     public LinuxStrategy(String text) { 
   3:         super(text); 
   4:     }
   5:  
   6:     public String replace() { 
   7:         preOperation(); 
   8:         System.out.println(
   9:                text = text.replaceAll("@r@n", "@n")); 
  10:         postOperation(); 
  11:  
  12:         return text; 
  13:     }
  14:  
  15:     private void preOperation() { 
  16:         System.out.println("LinuxStrategy preOperation"); 
  17:     }
  18:  
  19:     private void postOperation() { 
  20:         System.out.println("LinuxStrategy postOperation"); 
  21:     } 
  22: } 

  • WindowsStrategy.java
   1: public class WindowsStrategy extends TextStrategy { 
   2:     public WindowsStrategy(String text) { 
   3:         super(text); 
   4:     }
   5:  
   6:     public String replace() { 
   7:         startOperation(); 
   8:         System.out.println(
   9:                      text = text.replaceAll("@n", "@r@n")); 
  10:         endOperation(); 
  11:  
  12:         return text; 
  13:     }
  14:  
  15:     private void startOperation() { 
  16:         System.out.println("WindowsStrategy startOperation"); 
  17:     } 
  18:  
  19:     private void endOperation() { 
  20:         System.out.println("WindowsStrategy endOperation"); 
  21:     } 
  22: } 
  • TextCharChange.java
 
 
   1: public class TextCharChange { 
   2:     public static void replace(TextStrategy strategy) { 
   3:         strategy.replace(); 
   4:     } 
   5: }

  • Main.java
 
 
   1: public class Main { 
   2:     public static void main(String[] args) { 
   3:         String linuxText = 
   4:             "This is a test text!!@n Oh! Line Return!!@n"; 
   5:         String windowsText = 
   6:             "This is a test text!!@r@n Oh! Line Return@r@n"; 
   7:  
   8:         // load file, suppose it's Linux's text file 
   9:         // take the WindowsStrategy 
  10:         // I want to change it to Windows' text file 
  11:         TextCharChange.replace(
  12:               new WindowsStrategy(linuxText)); 
  13:  
  14:         // such-and-such operation..... 
  15:         System.out.println(); 
  16:  
  17:         // load file, suppose it's Windows' text file 
  18:         // take the LinuxStrategy 
  19:         // I want to change it to Linux's text file 
  20:         TextCharChange.replace(
  21:             new LinuxStrategy(windowsText)); 
  22:     } 
  23: }

为了明显的秀出结果,我们使用@n来表示 '/n' , @r 表示 '/r' 符号,Main中的流程是个假设的情况,何时采用何种策略是随机的。
在Strategy模式中,使用一个公开的介面replace(),让客户端请求,而在实作replace()时,可以任意的组合演算策略,程式中的 preOperation()、postOperation()就是用以示意演算的组合概念,Strategy模式封装了这些演算过程,使它们易于组合、 修改、替换,上面这个例子的UML 类别结构图如下所示:

Strategy

Strategy模式的UML类别结构图如下:

Strategy

从行为上来说,State 模式 与Strategy模式是相近的。
State模式:看当前是什么状态,就采取什么动作。
Strategy模式:看需求(情境)是什么,采用适当的策略。
不过两者虽相似,应用的场合稍有不同,State模式中有一个重点在于设定状态变化,就像 Gof 例子中举的TCP连线;Strategy策略模式则是直接采用适当的策略的感觉,例如Gof中说的,采用适当的演算法来作正文换行。

Edit by Atlas,

Time:09:50

目录
相关文章
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1008 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1703 9
|
8天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
646 152
|
10天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
614 12
|
10天前
|
人工智能 自然语言处理 API
Next AI Draw.io:当AI遇见Draw.io图表绘制
Next AI Draw.io 是一款融合AI与图表绘制的开源工具,基于Next.js实现,支持自然语言生成架构图、流程图等专业图表。集成多款主流大模型,提供智能绘图、图像识别优化、版本管理等功能,部署简单,安全可控,助力技术文档与系统设计高效创作。
688 151