文档章节

策略模式-常用设计模式

dapengking
 dapengking
发布于 2014/03/02 20:20
字数 1087
阅读 163
收藏 9
点赞 0
评论 2

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

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

    这次学习设计模式主要是通过看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
Java设计模式 create FactoryMethod

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

神勇小白鼠
2011/05/18
0
0
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

前言 今天我来全面总结开发中最常用的设计模式 - 代理模式中的动态代理模式 其他设计模式介绍 1分钟全面了解“设计模式” 单例模式(Singleton) - 最易懂的设计模式解析 简单工厂模式(Sim...

Carson_Ho
04/09
0
0
JavaScript常用设计模式

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

a独家记忆
07/13
0
0
javascript 设计模式之工厂(Factory)模式

工厂模式介绍 工厂模式是一个创建型的模式,主要就是创建对象。其中工厂模式又分为简单工厂模式和抽象工厂模式。简单工厂模式是通过工厂方法确定创建 对应类型的对象。抽象工厂模式是通过子类...

hlxiong
2014/04/14
0
0
java设计模式-- 单例模式

在很久之前,也就是在大二暑假的时候,那时候看马士兵的视频教程中有提到很多的设计模式。 java的设计模式大致可以分为3大类,23种设计模式。 其中,创建型模式有5种:单例模式、建造者模式、...

爱学习的逃课君
2014/11/27
0
0
设计模式什么的哪有那么神秘 ----第一集 一些吐槽和重构的韵味

一日面试, ...... Hr:你对设计模式熟悉吗? 应聘者A:我了解常用的设计模式,平时经常使用工厂模式和单例模式.而且我也看过一些讲23种设计模式的书.其他不常用的模式用的不是太熟. Hr:你用过外观...

架构梦想
2013/08/04
0
7
【设计模式笔记】(十六)- 代理模式

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

MrTrying
06/24
0
0
JavaScript 中常见设计模式-代理模式

     代理模式   情景:小明追女生 A   非代理模式:小明 =花=> 女生A   代理模式:小明 =花=> 让女生A的好友B帮忙 =花=> 女生A   代理模式的特点   代理对象和本体对象具有一...

webstack前端栈
06/15
0
0
Tomcat 系统架构与设计模式_ 设计模式分析

门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中、Standard Wrapper 到 ServletConfig 封装中、ApplicationContext 到 ServletContext 封装中等都用到...

lvzjane
2014/11/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spark Streaming + Kafka Integration Guide

The Spark Streaming integration for Kafka 0.10 is similar in design to the 0.8 Direct Stream approach. It provides simple parallelism, 1:1 correspondence between Kafka partition......

刺猬一号
12分钟前
0
0
数据结构与算法2

一个数组的例子,实现查找,显示和删除的功能。 在这个数组中存储的数据类型是long型,使用long型为的是表明这是数据,而int型被用来表示下标。通常数据结构存储的数据项包含有好几个字段,所...

沉迷于编程的小菜菜
23分钟前
0
0
Python3 基于 requests 批量下载图片

Python3 基于 requests 批量下载图片 import requestsheaders = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8','Accept-Encod......

leeyi
24分钟前
0
0
java获取当前时间所在一周的周一和周日日期

/** * 当前时间所在一周的周一和周日时间 * @param time 当前时间 * @return */ public static Map getWeekDate(String time) { Map map = new HashedMap(); SimpleDateFormat sdf = new Si......

小弱鸡
56分钟前
0
0
Redis数据的导出和导入(dump和load方式)

网上有些文章已经不再适用,本人也是踩了些坑,在此记录下。 迁移redis数据一般有如下3种方式: 第三方工具redis-dump,redis-load aof机制,需要开启aof功能 rdb存储机制 这里介绍第一种方式...

iplusx
今天
2
0
ElasticSearch 高亮显示大文档搜索结果

2016年12月,我们开始研究Ambar——一个文档搜索系统。Ambar使用ElasticSearch作为核心搜索引擎。 在Ambar开发的过程中,我们处理了很多与ES相关的问题,我们想分享我们得到的宝贵经验。让我...

九州暮云
今天
1
0
Python 使用 pywifi 模块 破解wifi密码

git https://github.com/awkman/pywifi 常见常量 from pywifi import const# Define interface status.IFACE_DISCONNECTED = 0IFACE_SCANNING = 1IFACE_INACTIVE = 2IFACE_CONNEC......

阿豪boy
今天
2
0
phpstorm使用Iedis

phpstorm的redis插件Iedis是真好用 看了网上挺多的文章,但是由于我系统还是ubuntu,就有点尴尬了,现在破解之后,留个笔记,即使自己之后有需要也可以很快翻阅 先下载资源 资源下载 zip压缩...

贤郎--均灵
今天
0
0
第三章 spring-bean之FactoryBeanRegistrySupport(4)

前言 从FactoryBeanRegistrySupport类的名字可以看出FactoryBeanRegistrySupport负责FactoryBean的注册与支持。如果想知道FactoryBean相关的资料,请阅读spring-bean中关于FactoryBean的解读...

鸟菜啊
今天
0
0
CentOS “Destination Host Unreachable”问题解决办法

挑战极速安装CentOS时遇到局域网主机不能通信的情况: [root@zjd network-scripts]# ping 8.8.8.8PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.64 bytes from 8.8.8.8: icmp_seq=1 ttl=......

wffger
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部