文档章节

策略模式-常用设计模式

dapengking
 dapengking
发布于 2014/03/02 20:20
字数 1087
阅读 163
收藏 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
策略模式和模板模式有啥区别吗
JavaScript设计模式之观察者模式

前言 准备研究一下MVVM的一些东西,由于MVVM运用了观察者模式的思想,因此翻开了《JavaScript设计模式与开发实践》一书,将观察者模式学习了一遍,顺便有对一些常用的设计模式进行一些了解,...

Srtian
05/22
0
0
编程中的那些经典套路——设计模式汇总

在正式阅读前,我先谈谈我们该用什么姿势和心态学习设计模式: 如果你还没有过多的编程经验(泛指半年以下),我建议你把它当做小说来看,能看懂多少是多少,因为半年以下经验的程序员用到设...

gzchen
08/27
0
0
编程中的那些套路——关于策略模式

该文章属于《编程中的那些经典套路——设计模式汇总》系列,并且以下内容基于语言PHP 今天讲讲策略模式,策略模式 和工厂模式十分相像(或者说在代码逻辑层面,他们是一样的)。 但策略模式与...

gzchen
08/27
0
0
Java设计模式 create FactoryMethod

工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。 为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经...

神勇小白鼠
2011/05/18
0
0
JavaScript常用设计模式

设计模式 设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案。 设计模式主要分为3类: 创建型设计模式:专注于处理对象的创建 Constructor构造器模式,Factory工厂模式,Singl...

a独家记忆
07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【转载】Linux升级安装GCC

https://itbilu.com/linux/management/V1vdnt9ll.html

goodman_fz
40分钟前
2
0
20.20 告警系统主脚本~20.22 告警系统监控项目

告警系统主脚本 main.sh内容 #!/bin/bash#Written by aming.# 是否发送邮件的开关export send=1# 过滤ip地址export addr=`/sbin/ifconfig |grep -A1 "ens33: "|awk '/inet/ {...

洗香香
42分钟前
2
0
07-利用思维导图梳理JavaSE-包与访问控制权限

07-利用思维导图梳理JavaSE-包与访问控制权限 主要内容 1.包的概念及使用 1.1.包的概念 1.2.包的作用 1.3.需要注意的问题 1.4.包的引用 2.系统常见包 2.1.java.lang包 2.2.java.io包 2.3.ja...

飞鱼说编程
43分钟前
2
0
【挑战剑指offer】系列02:替换空格

本系列的算法原题来自于“牛客网-剑指offer”,写这个板块,不仅仅是解决算法问题本身,更是手动提高难度、自行变式,思考更多的解决方案,以带给自己一些启发。 1. 【替换空格】原始题目 算...

LinkedBear
58分钟前
1
0
Win10内部更新:警告用户别用chrome和Firefox

简评:别和 Chrome 和 Firefox 约行不,我 Edge 明明更美、屁股更翘、更性感。。。 微软正在测试 Windows 10 的一个更新:警告用户不要安装 Chrome 和 Firefox。是测试人员发现的这个新警告,...

极光推送
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部