策略模式(Strategy)
策略模式(Strategy)
策略模式(Strategy)[Policy]
意图:定义一系列算法,把他们封装起来,并且使他们可以相互替换,使算法可以独立于使用它的客户而变化。
应用:排序的比较方法、封装针对类的不同的算法、消除条件判断、寄存器分配算法等。
模式结构:
心得:
对对象(Context)的处理操作可能有很多方式,这些方式很多情况下是同一类的处理操作,区别仅仅是操作的具体内容的差别。一般会通过条件分支判断不同的算法或者使用继承产生不同处理算法对应的对象。但是这么做的扩展性都很差,如果把对同一数据的不同处理方式封装起来,继承于统一的接口,就可以封装这些变化,达到扩展性的目的。
举例:
被处理的Context对象可以看作一组数据,现在需要对该数据进行排序,但是排序的方式无法确定。也就说如何比较元素的大小是由用户来选择的,那么用户选择的变化性可以封装在具体的策略对象ConcreteStrategy内部,根据用户选择生成不同方式的策略对象,然后Context只需要一个抽象的Strategy引用该对象,操作它的接口来决定排序的方式就可以了。
这里涉及Context类和Strategy交互的问题,Context需要Strategy提供的算法进行计算,那么源数据如何告知Strategy类就有两种方式:一种是通过参数传递,直接将数据传参到Strategy的接口algorithmInteface即可,另一种是直接传递Strategy对象的指针,并提供公共的访问接口contextInterface来提供数据来源。最后通过algorithmInteface获取算法策略的返回值。这里为了方便,我们使用简单的值传递示例,C++实现如下:
class Strategy
{
public:
virtual bool algorithmInterface(int x,int y)=0;
virtual ~Strategy(){}
};
class UpStrategy:public Strategy
{
public:
virtual bool algorithmInterface(int x,int y)
{
return x<y;
}
};
class DownStrategy:public Strategy
{
public:
virtual bool algorithmInterface(int x,int y)
{
return x>y;
}
};
class Context
{
Strategy*pStrategy;
public:
Context(Strategy*ps):pStrategy(ps){}
void sort()
{
if(pStrategy->algorithmInterface(1,2))
{
cout<<"1,2有序"<<endl;
}
else
{
cout<<"1,2反序"<<endl;
}
}
~Context()
{
delete pStrategy;
}
};
客户使用代码如下:
Context c1(new UpStrategy());
c1.sort();
Context c2(new DownStrategy());
c2.sort();
UpStrategy和DownStrategy决定比较的数据是升序还是降序,比较的结果通过统一接口algorithmInterface返回到调用者Context的sort函数中。使用时创建策略子类传递给Contex对象,而不用修改sort函数本身。如果要添加其他的比较方式,只需要添加一个策略子类就可以了。
参考文章:http://www.dedecms.com/knowledge/program/jsp-java/2012/0822/12106.html
- Pandas-DataFrame基础知识点总结
- python mongodb爬取58网站
- 洛谷P1143 进制转换
- python爬取链家租房之获取北京所有区的网站分栏地址(第一次写,code太粗犷,欢迎提建议)
- Pandas-Series知识点总结
- Numpy基础知识点汇总
- P3388 【模板】割点(割顶)
- python爬取链家租房之获取房屋的链接和页面的详细信息
- 信用卡“坏账”客户分析(一)
- 一道简单的sql语句题
- python爬虫反爬取---设置User Agent自动变换header文件
- 一文读懂Python多线程
- 深入理解Python变量作用域与函数闭包
- TensorFlow从1到2 - 5 - 非专家莫入!TensorFlow实现CNN
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 深入探究immutable.js的实现机制(二)
- ES6 Promise 的最佳实践
- 「 Map最佳实践」什么时候适合使用 Map 而不是 Object
- ES2017 异步函数的最佳实践(`async` /`await`)
- React Hooks中这样写HTTP请求可以避免内存泄漏
- 用了这 7 个 VS Code 插件,想写一辈子代码
- 听说你还不知道Promise的allSettled()和all()的区别?
- React 条件渲染最佳实践(7 种方法)
- 一文带你层层解锁「文件下载」的奥秘
- Android实现简单C/S聊天室应用
- Android仿IOS回弹效果 支持任何控件
- 送你一道字节前端原题(Add sumOf)|文末送红宝书
- xadmin使用formfield_for_dbfield函数过滤下拉表单实例
- Python3之外部文件调用Django程序操作model等文件实现方式
- python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)