Head First-策略模式解读

一、概括:

策略模式无论是在大话设计模式中还是在Head First中都是作为前面出现的设计模式,可见它还是相对比较简单的。

策略是行为型的,也就是说它的侧重点在方法上。

二、谈谈认识:

现在通过模拟鸭子的实例,谈谈策略。

第一层:单纯继承

首先,各种鸭子,一边游泳,一边呱呱叫。我们很容易的从中取出类:鸭子;方法:游泳、叫、外观。所以,我们画出来是酱紫的:

代码实现:

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 15:44:32
 */
public abstract class Duck {

	public Duck(){

	}

	public void display(){

	}

	public void fly(){

	}

	public void queck(){

	}

	public void swim(){

	}

}

子类:(只写一个)

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 15:44:32
 */
public class MallardDuck extends Duck {

	/**
	 * 外观是绿头
	 */
	public void display(){

	}

}

第二层:加入接口

当然,到这一步我们是不满意的,每一个子类都与父类不同,那就会产生很多的代码。比如我加了一个橡皮鸭,不会飞,却继承了父类中的fly方法。比如加入了一个诱饵鸭,它不会飞也不会叫。为了解决这个问题,我们引入了接口。

光看这个图就挺乱的,我们要记得,接口定义了fly这个方法,但是并没有实现它。MallarDuck和RedheadDuck他们两个fly实现是相同的,这个时候,非要让他们重写接口中的fly方法,这不是又生成了大量的重复代码吗?

因此我们进行进一步整合,通过对父类的引用指向子类对象的方式。

第三层:策略模式

其中要注意的点:

1、各种fly方法继承接口FlyBehavior,封装起来。这样可以达到代码的复用。

2、Duck抽象类中添加成员变量为FlyBehavior flyBeHavior。(如果一个类是另一个类中的成员变量,则这两个类的关系是聚合关系)。这样可以抽象类就可以将fly动作委托给FlyBehavior类了。

3、Duck中setFlyBehavior中的局部参数就是FlyBehavior。这样就实现了动态调用,setFlyBehavior中参数得到的是哪一个fly的子类,就可以调用哪一个了。

4、Duck中performQuack方法,应用了委托,直接调用的是该接口FlyBehavior中的子类的fly对象。

代码:

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:39
 */
public abstrack class Duck {

	FlyBehavior  flyBehavior;     //成员变量
	QuackBehavior quackBehavior;

	public Duck(){

	}

	public abstract void display(){

	}

	public void performQuack(){
            flyBehavior.fly();        //将fly动作委托给了FlyBehavior类
	}

	public void performQuack(){
	    quackBehavior.quack();

	}

	/**
	 *
	 * @param fb
	 */
	public void setFlyBehavior(FlyBehavior fb){
	    fyBehavior = fb;             //动态的指向子类对象

	}

	/**
	 *
	 * @param qb
	 */
	public void setQuackBehavior(QuackBehavior qb){
	    QuackBehavior = qb;
	}

	public void swim(){
	   System.out.println("All ducks float, even decoys!");

	}

}

子类继承父类(只写一个):

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:40
 */
public class MallardDuck extends Duck {

    public MallardDuck(){
       flyBehavior = new FlyNoWay();
       quackBehavior = new Quack();

    }

    public void display(){
       System.out.println("I'm a mallard duck!");
    }

}

接口FlayBehavior:

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:39
 */
public interface FlyBehavior {

	public void fly();

}

实现接口的FlyRocketPowered(只写一个):

/**
 * @author qmx
 * @version 1.0
 * @created 21-九月-2014 16:47:40
 */
public class FlyWithWings implements FlyBehavior {

	public void fly(){
	    System.out.println("I'm flying with my wings!");
	}

}

这样写客户端调用时:

	    Duck mallard = new MallardDuck();            <pre name="code" class="java">            mallard.performFly();          //为“I'm not fly!”

mallard.setFlyBehavior(new FlyWithWings()); mallard.performFly(); //为“I‘m flying with my wings!”


三、总结

之前设计模式中的策略其实在机房收费系统中的结账的时候,用策略+职责链一起用过,在职责链的强大阵容下,策略显得总是有点微小,心想是不是可以不用总结了,看似好像会了,但实际上,这篇博客用java的语言从新再写一边的时候,觉得学习到了很多。

感想就是:知识当你看过一遍觉得你都会了的时候,其实你只回了20%到30%;当你动手做了一遍的时候,其实你会了50%;当你思考了,并且总结了,你会了70%到80%;当你和别人分享你的知识,同时不断交流,你就可以说你是大牛了。

时间: 2024-12-28 12:56:48

Head First-策略模式解读的相关文章

设计模式解读之一: 策略模式

1. 模式定义 把会变化的内容取出并封装起来,以便以后可以轻易地改动或扩充部分,而不影响不需要变化的其他部分: 2. 问题缘起当涉及至代码维护时,为了复用目的而使用继承,结局并不完美.对父类的修改,会影响到子类型.在超类中增加的方法,会导致子类型有该方法,甚至连那些不该具备该方法的子类型也无法免除.示例,一个鸭子类型: public abstract class Duck {    //所有的鸭子均会叫以及游泳,所以父类中处理这部分代码    public void quack() {     

Java设计模式6:策略模式

策略模式 策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包装,是把使用算法的责任和算法本身分开.策略模式通常是把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类. 策略模式涉及到三个角色: 1.环境角色 持有一个策略Strategy的引用 2.抽象策略角色 这是一个抽象角色,通常由一个接口或抽象类实现,此角色给出所有具体策略类所需的接口 3.

(转)组合优于继承---设计模式之策略模式

文章来源:http://www.javaeye.com/topic/328262 当我们掌握了Java的语法,当我们了解了面向对象的封装.继承.多态等特性,当我们可以用Swing.Servlet.JSP技术构建桌面以及Web应用,不意味着我们可以写出面向对象的程序,不意味着我们可以很好的实现代码复用,弹性维护,不意味着我们可以实现在维护.扩展基础上的代码复用.一把刀,可以使你制敌于无形而于江湖扬名,也可以只是一把利刃而使你切菜平静.Java,就是这把刀,它的威力取决于你使用的方式.当我们陷入无尽

大话设计模式之策略模式读后感

策略模式:定义了算法家族,分别封装起来,让他们呢之间可以互相的替换,此模式让算法的变化不会影响到使用算法的客户. UML类图: 解读:策略模式是定义一系列的算法,从概念上来讲,这些算法完成的工作都是一样的,只是他们的实现的不同,可以以相同的方式调用所有的算法,减少了各种算法类和算法调用类之间的耦合. 策略模式中的supperStrategy为context类提供了一系列的可供重用的算法或者行为.继承有助于提取出这些算法的公共功能. 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转

PHP设计模式-策略模式

<?php//策略模式//将一组特定的算法或行为 封装成一个类,以适应上下文环境 //策略的接口文件 约定策略的行为 针对一种情况 产生具体的策略interface Policy{ function showAd();} class Female implements Policy{ public function showAd() { echo __CLASS__.' policy'; }} class Male implements Policy{ public function showA

对设计模式的总结之简单工厂与策略模式

前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓,本文就说说我对本人对简单工厂模式.策略模式的见解. 简单工厂模式与策略模式 简单工厂模式 工作中,常常遇到需要做一个功能(鸭子),这个功能中含有可控个数的子操作功能(鸭子叫,鸭子跑,鸭子飞),而且子功能在不同的情况下处理方式又不相同(成年鸭子/小鸭子叫,成年鸭子/小鸭子跑,成年鸭子/小鸭子飞).我

Java 策略模式

Java 策略模式 @author ixenos 定义 1.封装算法:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换 2.分割行为和环境:对用户屏蔽内部实现,使客户端在调用算法的时候能够互不影响地互换 策略模式的实现(面向接口编程) 方法: 1.接口多态:策略模式的用意是针对一组算法,将每个算法封装到具有共同接口的独立的类中,从而使他们之间可以相互替换 2.具体策略提供不同算法,环境负责维持和查询策略,把具体策略和环境分割开来,使得算法可以在不影响客户端和环境的情况下修改 角色分工:

设计模式之策略模式

一.概述我们来实现一个企业的工资系统,该企业中不同级别的员工工资算法都不相同,针对该问题,最容易想到的莫过于在代码中堆积一大堆if…else…语句或者是switch…case…语句.如果该企业中不同级别的员工过多,或是对级别的调整比较频繁,那该系统就会显得复杂而脆弱.如何能将对象和算法解耦,从而使得在系统运行时能透明的改变对象的算法呢?这就到了策略模式大显身手的时候了.二.策略模式策略模式定义了一系列算法,把它们一个个封装起来,并且使它们可相互替换.该模式可使得算法能独立于使用它的客户而变化.策

设计模式之桥梁模式和策略模式的区别

桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式.以下是它们的UML结构图. 桥梁模式: 策略模式: 在桥接模式中,Abstraction通过聚合的方式引用Implementor. 举一个例子: 策略模式:我要画圆,要实心圆,我可以用solidPen来配置,画虚线圆可以用dashedPen来配置.这是strategy模式. 桥接模式:同样是画圆,我是在windows下来画实心圆,就用windowPen+solidPen来配置,在unix下画实心圆就用uni

Strategy Design Pattern(策略模式)

策略模式意义在于,当我们有多种不同的算法时,程序能够动态的选择算法进行计算. 策略模式的另外一个英文名字是Policy Strategy. 策略模式最典型的里一个例子就是JAVA中复杂对象的排序(java.util.Arrays.sort,java.util.Collections.sort),用户可以自己定义各种排序算法(规则),然后在需要排序时将算法传给排序函数.从而实现排序方式的变化,获得不同的排序结果.参见:http://my.oschina.net/nox/blog/487478 下面