ITKeyword,专注技术干货聚合推荐

注册 | 登录

Head First设计模式学习—模板方法、策略模式

zlp1992 分享于 2016-08-02

推荐:调侃《Head First设计模式》之模板方法模式

      现在有两个人,一个爱喝咖啡,一个爱喝茶,让我们用代码创建咖啡和喝茶:      咖啡类:           茶类:           很容易发现,咖啡喝茶的代码有惊人的

参考资料: 1. head first 设计模式 2. http://blog.csdn.net/hguisu/article/details/7558249/ 在看设计模式的时候,总觉得好多设计模式都差不多,容易弄混,因此做点记录。 一、模板方法 模板方法模式在一个方法中定义了一个算法的步骤(骨架),而将一些步骤延迟到子类中。模板方法使得子类在不改变算法结构的情况下,重新定义算法中的某些步骤。模板方法模式的一般结构如下图所示: 注:图片来自Head First 设计模式中文版截图 可以看到模板方法模式一般是针对一个算法的各个步骤进行操作,算法的步骤由超类AbstractClass控制,子类ConcreteClass只是实现了父类算法的某几个步骤,本身并不控制算法流程(这点要与下面的策略模式区分)。模板方法模式有几个好处: 算法流程只由超类AbstractClass控制,子类无法去修改算法流程(比如算法的执行顺序等,不过可以通过在父类中加入像“钩子”的方法实际上是可以修改算法流程),但是可以修改算法中的某个步骤细节。这样要修改算法比较容易,同时也保护了算法(毕竟只由AbstractClass一个类控制) 算法中通用的步骤可以放在超类中实现,利用继承实现了代码复用 举个可能比较牵强的例子,比如我在北京,要回到江西去,有一种路线是:北京->武汉->江西,那么这里 北京->武汉->江西 这个路线流程就是从北京去往江西的一个算法,这个算法分成了两个步骤:北京->武汉,武汉->江西,假设北京到武汉只有高铁,那我只能坐高铁了,但是从武汉到江西既有高铁又有硬座,于是我们设计的代码结构如下: /** * 从北京到江西路线算法框架类,确定了整体框架,其中某些步骤需要子类具体实现 * */public abstract class AbstractFromBeijingToJiangXi {

/** * 算法框架,定义成final,避免子类去修改算法框架 * */

public final void fromBeijingToJiangXi(){

fromBeijingToWuHan();

fromWuhanToJiangXi();

}

/** * 这个是算法步骤中变化的步骤,不同的子类有不同的实现 * */

public abstract void fromWuhanToJiangXi();

/** * 这个是算法的通用步骤,子类不需要实现 * */

public final void fromBeijingToWuHan(){

System.out.println("坐高铁从:北京 -> 武汉");

}} 以下是两个子类的实现: /** * 坐高铁 * */public class CRHFromBeijingToJiangXi extends AbstractFromBeijingToJiangXi{

/** * 子类重写的步骤 * */

@Override

public void fromWuhanToJiangXi() {

System.out.println("坐高铁从:武汉 -> 江西 ");

}} /** * 做普通硬座 * */public class NormalFromBeijingToJiangXi extends AbstractFromBeijingToJiangXi {

@Override

public void fromWuhanToJiangXi() {

System.out.println("坐硬座从:武汉-> 江西 ");

}} 我们这样使用: public class Client {

public static void main(String[] args) {

//AbstractFromBeijingToJiangXi road=new CRHFromBeijingToJiangXi();

AbstractFromBeijingToJiangXi road=new NormalFromBeijingToJiangXi();

road.fromBeijingToJi

推荐:iOS开发设计策略模式

iOS应用能加密?全球都没有的技术,你造吗?作为开发iOS应用的,是不是感到自己out啦?快来看看什么是iOS应用加密:http://www.ijiami.cn/newsInfoid=5

angXi();

}} 二、策略模式 策略模式定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。还是以上面的例子为例,从北京到江西,可以有多种交通方案(每种交通方案相当于一个算法)。得到如下的代码结构: /** * 算法族的公共接口 * */public interface IFromBeijingToJiangXi {

/** * 不同的算法有不同的实现,子类完全控制算法的步骤流程 * */

public void fromBeijingToJiangXi();} 子类完全自己实现算法 /** * 坐高铁 * */public class CRHFromBeijingToJiangXi implements IFromBeijingToJiangXi{

/** * 子类自己完全实现算法的流程 * */

@Override

public void fromBeijingToJiangXi() {

fromBeijingToWuHan();

fromWuhanToJiangXi();

}

public void fromBeijingToWuHan(){

System.out.println("坐高铁从:北京-> 武汉 ");

}

public void fromWuhanToJiangXi(){

System.out.println("坐高铁从:武汉->江西 ");

}} /** * 做普通硬座 * */public class NormalFromBeijingToJiangXi implements IFromBeijingToJiangXi {

/** * 子类自己完全实现算法的流程 * */

@Override

public void fromBeijingToJiangXi() {

fromBeijingToWuHan();

fromWuhanToJiangXi();

}

public void fromBeijingToWuHan(){

System.out.println("坐硬座从:北京-> 武汉 ");

}

public void fromWuhanToJiangXi(){

System.out.println("坐硬座从:武汉->江西 ");

}} 如何使用: public class Client {

private IFromBeijingToJiangXi fromBeijingToJiangXi;

public Client(IFromBeijingToJiangXi fromBeijingToJiangXi){

this.fromBeijingToJiangXi=fromBeijingToJiangXi;

}

public void travel(){

fromBeijingToJiangXi.fromBeijingToJiangXi();

}

public static void main(String[] args) {

//客户端使用时需要事先知道对应的具体的算法

IFromBeijingToJiangXi fromBeijingToJiangXi=new CRHFromBeijingToJiangXi();

//可以换不同的算法

//IFromBeijingToJiangXi fromBeijingToJiangXi=new NormalFromBeijingToJiangXi();

Client client=new Client(fromBeijingToJiangXi);

client.travel();

}} 三、 二者的区别 1. 二者针对的对象的粒度不同,给我感觉模板方法模式是以算法的步骤为单位,而策略模式是以算法为单位 2. 模板方法模式的子类只修改了算法的某些步骤,并不会去改变算法的框架流程,而策略模式的子类则自己完全定义了算法的步骤和流程

推荐:设计模式学习-----模板方法模式

模板方法模式                  GOOD:把不变的代码部分都转移到父类中,将可变的代码用virtual留到子类重写。 迪米特法则      如果两个类不直接通信,那

参考资料: 1. head first 设计模式 2. http://blog.csdn.net/hguisu/article/details/7558249/ 在看设计模式的时候,总觉得好多设计模式都差不多,容易弄混,因此做点记录。 一、模板方法 模板

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。