文档章节

策略模式-常用设计模式

dapengking
 dapengking
发布于 2014/03/02 20:20
字数 1087
阅读 165
收藏 9

    离毕业还有一段时间。最近闲来无事,打算系统的学习下设计模式。

    专门在博客里面新开了一个分类,主要记录下自己对常用设计模式的理解。同样还是算对自己的一个敦促吧。争取两天一篇吧。

    这次学习设计模式主要是通过看Headfirst系列的设计模式一书。之所以选择这本书,来入门,是因为身边挺多同学,看过这个,并且十分推荐。我之前也大概浏览过,我想大家之所以这么推荐的原因可能是因为,headfirst系列一贯都有深入浅出,语言风趣幽默的特点吧。好了,兴趣是最好的老师。配着插图学技术,感觉也不是什么坏事是吧?~

-----我是分割线------------------------------------------------------------

策略模式

    策略模式,在headfirst设计模式中的定义是这样的:策略模式定义了算法族,分别封装起来,让它们之前可以相互替换。这个模式可以使算法的变化独立于使用算法的客户。

    UML类图:

(上图转自百度图片)

对应书中的定义。strategy接口,定义了策略类的公共接口。也就是书中定义的需要进行单独封装的算法。在代码中,我们可以自行实现任意多个Strategy的实现类,例如:ConcreteStrategyA,ConcreteStrategyB。。。

在这些实现中,我们需要实现接口中AlgorithmInterface()方法,作为具体的算法。

在Context类中,维护了一个Strategy类型的引用。用来引用一个具体的ConcreteAtrategyA等类型的具体算法对象。这里采用父类引用指向子类对象的方式,可以方便利用面向对象的多态的特性。

然后在Context对象的ContextInterface()方法中,通过Strategy类型的引用,调用具体的Strategy实现类对象中的AlgorithmInterface()方法,完成具体的工作。

说道这里,其实用一句话就可以总结:策略模式,其实最核心的地方就是,它是采用组合而非继承,来实现对算法代码的复用的。这也体现出了,我们在代码设计中的一个常用的原则就是--尽量使用组合,而尽量少用继承。

主要区别如下:


  1. 首先,继承是代码的编译期间实现的。
  2. 而,组合则是在程序运行时实现的。

倒不是说,在编译期实现有什么不好。主要是因为当我们采用组合的方式实现时,就可以在程序运行时具有非常的灵活性。试想,你可以在程序运行的过程当中,通过将新的Strategy实现类ConcreteStrategyC的对象实例,赋值给Context成员Strategy引用,这样就可以在ContextInterface()中,通过引用调用全新的算法实现了。而这种动态所带来的灵活性是继承的方式所没有的。(当然,继承也是一种实现代码复用的重要手段。但并不是唯一手段,这是像我这样的新手经常忽略的问题。因为我在写代码的时候,动不动就喜欢采用继承的方式。好像使用了继承,就是使用了OO的设计思路。就能达到比较好的代码复用效果。)

例子代码:

package strategy;

public interface Strategy {

	public void AlgorithmInterface();
}



package strategy;

public class ConcreteStrategyA implements Strategy {

	@Override
	public void AlgorithmInterface() {
		//这里是算法的具体实现
		//
		//
		System.out.println("ConcreteStrategyA");
		
	}

}



package strategy;

public class ConcreteStrategyB implements Strategy {

	@Override
	public void AlgorithmInterface() {
		//这里是算法的具体实现
		//
		//
		System.out.println("ConcreteStrategyB");
		
	}

}



package strategy;

public class Context {

	private Strategy s = null;

	public Strategy getS() {
		return s;
	}

	public void setS(Strategy s) {
		this.s = s;
	}

	public Context(Strategy s) {
		this.s = s;
	}
	
	public void ContextInterface(){
		s.AlgorithmInterface();
	}
	
	public static void main(String[] args) {
		Context c = new Context(new ConcreteStrategyA());
		c.ContextInterface();
		//灵活的动态改变算法的具体实现
		c.setS(new ConcreteStrategyB());
		c.ContextInterface();
	}
}



运行结果:




the end~

(小学语文水平,标点符号用的也比较乱。可能是写少的原因吧。想想上次写作文,也差不多是七八年前的事情了。嗯,慢慢写的多了应该就好了。这对自己应该也算是一个锻炼吧。O(∩_∩)O~)


© 著作权归作者所有

共有 人打赏支持
dapengking
粉丝 7
博文 133
码字总数 53553
作品 0
东城
程序员
私信 提问
加载中

评论(2)

dapengking
dapengking

引用来自“lgscofield”的评论

策略模式和模板模式有啥区别吗

呵呵,我刚开始看,实话说,还不知道什么叫模板模式。刚在网上找了篇帖子(http://tianli.blog.51cto.com/190322/45564/)大概读了下。如果理解的没有偏差的话,模板模式主要的概念应该是:算法的框架封装在基类中,将算法中的差异性通过抽象方法接口的形式,留给具体的子类去实现。这样做带来的好处是可以通过继承的方式复用代码。但更重要的优势是,通过基类中对算法框架的封装定义,使算法的用户在实现具体的实现类时,可以不用考虑算法的骨架,而只用专心实现算法在不同适用情况下的差异就行了。
至于,策略模式和模板模式的区别。我也在网上找到了一个帖子(http://blog.csdn.net/klarclm/article/details/7164227),回答了这个问题。

我自己的理解是,这两种模式,还是比较容易区分的。虽然它们的优势都是带来的代码复用的方便。但是采用的确实截然不同的两种方式:”组合和继承“。与其说这两种模式的区别在哪,我感觉主要还是看在什么情况下最适合使用哪种模式来工作。
正像帖子中总结的那样:
Strategy模式的应用场景是:
1. 多个类的分别只是在于行为不同
2. 你需要对行为的算法做很多变动
3. 客户不知道算法要使用的数据



Template Method模式的应用场景是:
1. 你想将相同的算法放在一个类中,将算法变化的部分放在子类中实现
2. 子类公共的算法应该放在一个公共的类中,避免代码重复

还有一点:
有一个说法总结得不错: 到底该倾向于composition还是inheritance,决定于"变化的是什么".如果基类的接口变化得很频繁,那么使用inheritance绝对是个噩梦;如果只是给基类新增方法,那么坚持使用composition的话就得新增很多个delegate.
这么说来,Strategy与Template Method模式之间的区别,也是在"变化的是什么"这个问题上了.

ps:发了这么多帖子,您还是第一个给我留言的。今天挺高兴的~0
lgscofield
lgscofield
策略模式和模板模式有啥区别吗
六个前端开发工程师必备的Web设计模式/模块资源

Yahoo的设计模式库 Yahoo的设计模式库包含了很多可以帮助开发设计人员解决遇到的问题的资源,包括开发中常常需要处理的导航,互动效果及其布局网格等大家常用的组件和模块 响应式设计模式库 ...

gbin1
2014/07/30
13
0
Ubuntu中vi卸载与安装/使用模式

Ubuntu中安装的vi是vim-common版本,与centos系统中vi使用方式不同,编辑使用不惯, 遂卸载重装,卸载命令:sudo apt-get remove vim-common 卸载完毕后重新安装;输入命令:sudo apt-get in...

唐十三郎
2018/11/27
0
0
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
2018/06/24
0
0
设计模式已经陨落了?

你现在是坐在一个程序员旁边吗?如果是的话,那么在你读下面的段落之前,有一个简单的实验。让他们到一边去,问问他们两个问题并记录下答案。首先问他们“什么是设计模式?”然后再问“说出你...

oschina
2014/03/11
9.1K
69
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
2018/11/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 风扇写着先生请自爱

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @蚂蚁哈哈哈 :分享陈奕迅的单曲《落花流水》 《落花流水》- 陈奕迅 手机党少年们想听歌,请使劲儿戳(这里) @车谷 :我发现每天上班都好困 ...

小小编辑
52分钟前
6
0
centos7重置密码、单用户模式、救援模式、ls命令、chmod命令

在工作当中如果我们错误的配置了文件使服务器不能正常启动或者忘记密码不能登录系统,如何解决这些问题呢?重装系统是可以实现的,但是往往不能轻易重装系统的,下面用忘记密码作为例子讲解如...

李超小牛子
今天
3
0
Python如何开发桌面应用程序?Python基础教程,第十三讲,图形界面

当使用桌面应用程序的时候,有没有那么一瞬间,想学习一下桌面应用程序开发?行业内专业的桌面应用程序开发一般是C++,C#来做,Java开发的也有,但是比较少。本节课会介绍Python的GUI(图形用...

程序员补给栈
今天
8
0
kafka在的使用

一、基本概念 介绍 Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。 这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统...

狼王黄师傅
今天
3
0
Android JNI总结

0x01 JNI介绍 JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。 JNI在Android中起着连接Java和C/C++层的作...

天王盖地虎626
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部