文档章节

设计模式学习笔记-策略模式

贲大侠
 贲大侠
发布于 2016/11/22 18:21
字数 1300
阅读 10
收藏 0
点赞 1
评论 0

        策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

        上面这段话是《Head First》对第一章策略模式的最后总结,起初看书时候我十分看不明白书中所说的算法族是啥意思,看书中的代码“封装行为”,一个接口,多个类实现,每个实现类都被比喻做算法族。

比如:
       一只鸭子(可能是玩具鸭子,还可能是有生命的鸭子)。它可以飞,可以叫。把它“飞”和“叫”看做行为。行为分为很多种,比如玩具鸭子不具备叫的功能,有生命的鸭子可以叫,玩具鸭子不能飞,有生命的鸭子可以飞。有的鸭子也可能叫声不同,非得方式也不同。这个时候封装一个“飞”的行为,然后用多个类实现。具体看下面的代码:

//飞行行为接口
public interface FlyBehavior {
    //飞
    public void fly();
}
//实现飞行接口,这个实现类被定义为不能飞
public class FlyNoWay implements FlyBehavior{
    //实现飞行行为方法
    @Override
	public void fly() {
		System.out.println("不能飞");
	}
}
//实现飞行接口,这个实现类被定义为可以飞
public class FlyWithWings implements FlyBehavior{
    //实现飞行方法
	@Override
	public void fly() {
		System.out.println("可以飞哦");
	}
}

        每一个实现类(行为)被看做一个算法族。同理,鸭子叫的行为也和上面实现方式一样,具体看下面的代码:

//鸭子叫行为接口
public interface QuackBehavior {
    //叫
	public void quack();
}
//实现叫行为接口,这个接口被定义为哇哇叫
public class Squeak implements QuackBehavior {
    //鸭子哇哇叫
	@Override
	public void quack() {
		System.out.println("哇哇哇");
	}
}
//实现叫行为,这个接口被定义为嘎嘎叫
public class Quack implements QuackBehavior{
    //鸭子嘎嘎叫
	@Override
	public void quack() {
		System.out.println("嘎嘎嘎");
	}
}
//实现叫行为,这个接口被定义为不能叫
public class MuteQuack implements QuackBehavior{
    //不能叫
	@Override
	public void quack() {
		System.out.println("无法叫");
	}
}

        这个时候,我们要实现很多个鸭子都有不同的“飞”和“叫”的行为。        

        定义一只鸭子抽象类当做父类,因为鸭子有很多种,看上去不同,但本质是一样的,都是鸭子。(我的思维比较逆向...觉得我顺序不对的大牛请忍耐一下..)

public abstract class Duck {
    //书中说道,鸭子里面要"有一个",也就是,每个鸭子都"有一个"飞行行为和叫行为,
    //代码上来看就是在鸭子类里面声明"飞行为"和"叫的行为",也就是下面这俩
    //这样每只集成了父类鸭子的子鸭子都会引用实现行为接口的对象
	FlyBehavior flybehavior;

	QuackBehavior quackBehavior;

    //写一个方法取代 fly()
	public void performQuack() {
		quackBehavior.quack();//父类鸭子对象不亲自处理使用 嘎嘎嘎 还是 哇哇哇 而是委托给行为引用的对象
	}

    public void performFly() {
		flybehavior.fly();
	}
}

        然后开始写子鸭子

//子鸭子继承父鸭子
public class MallardDuck extends Duck{
	public MallardDuck(){
		quackBehavior = new Squeak();//这只鸭子可以哇哇叫
		flybehavior= new FlyWithWings();//这只鸭子可以飞
		this.display();
	}
	
	public void display(){
		System.out.println("红鸭子!");
	}
}
//子鸭子继承父鸭子
public class ModelDuck extends Duck{
	public ModelDuck(){
		flybehavior= new FlyNoWway();//这鸭子不能飞
		quackBehavior = new Quack();//可以叫
		this.dispay();
	}
	
	public void dispay(){
		System.out.println("玩具鸭");
	}
}

        然后编写个测试类感受一下

public class MinDuckSimulator {
 public static void main(String[] args) {
		Duck mallardDuck = new MallardDuck();
        //这里会调用红鸭子继承来的performQuack()方法,进而委托给行为对象来处理。
		mallardDuck.performFly();
		mallardDuck.performQuack();

        Duck modelDuck = new ModelDuck();
		modelDuck.performFly();
		modelDuck.performQuack();
 }
}

        运行结果:

红鸭子
可以飞
哇哇哇

模型鸭
不能飞
嘎嘎嘎

        接下来实现鸭子动态设定行为

public abstract class Duck {
    //书中说道,鸭子里面要"有一个",也就是,每个鸭子都"有一个"飞行行为和叫行为,
    //代码上来看就是在鸭子类里面声明"飞行为"和"叫的行为",也就是下面这俩
    //这样每只集成了父类鸭子的子鸭子都会引用实现行为接口的对象
	FlyBehavior flybehavior;

	QuackBehavior quackBehavior;

    //写一个方法取代 fly()
	public void performQuack() {
		quackBehavior.quack();//父类鸭子对象不亲自处理使用 嘎嘎嘎 还是 哇哇哇 而是委托给行为引用的对象
	}

    public void performFly() {
		flybehavior.fly();
	}

    //我们在父类鸭子类里面增加两个set方法
    public void setFlyBehavior(FlyBehavior fb) {
		flybehavior= fb;
	}

	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}
}

        测试

public class MinDuckSimulator {
 public static void main(String[] args) {
		Duck mallardDuck = new MallardDuck();
		mallardDuck.performFly();
        //之前红鸭子默认是用哇哇哇的方式来叫
        mallardDuck.setQuackBehavior(new Quack());//在这里调用继承来的set方法 动态设置鸭子的叫声
		mallardDuck.performQuack();

        Duck modelDuck = new ModelDuck();
		modelDuck.performFly();
		modelDuck.performQuack();
 }
}

结果

红鸭子
可以飞
嘎嘎嘎

模型鸭
不能飞
嘎嘎嘎

        利用继承来提供鸭子行为也有很多缺点,比如有的代码在多个子类中有很多重复,并且很难知道鸭子所有的行为。但策略模式提供了管理相关的算法族的办法,恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码

© 著作权归作者所有

贲大侠
粉丝 1
博文 18
码字总数 17703
作品 0
海淀
程序员
Head First Design Pattern 读书笔记(1) 策略模式

Head First Design Pattern 读书笔记(1) Strategy Pattern 策略模式 这几天为了锻炼看英语文档的能力,开着有道硬着头皮看 《Head First Desgin Pattern》的原版书,顺便做下笔记,把里面提...

Tek_Eternal
2015/01/02
0
0
代理模式(Proxy Pattern):动态代理 - 最易懂的设计模式解析

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

Carson_Ho
04/09
0
0
Happy 设计模式之工厂模式(Java)

闲暇之余学习设计模式。只是把我理解的整理成笔记,如果有不对的地方,请各位大牛指出。 工厂模式 1、简单工厂模式、 2、工厂方法模式、 3、抽象工厂模式、 下面首先介绍简单工厂模式: 先看...

豆芽菜橙
07/03
0
0
C#设计模式(2)——简单工厂模式

一、引言   这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式——简单工...

技术小胖子
2017/11/08
0
0
JavaScript设计模式之观察者模式

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

Srtian
05/22
0
0
(目录)设计模式(可复用面向对象软件的基础)

本系列“设计模式”博客使用Golang语言实现算法。所谓算法是指解决一个问题的步骤,个人觉得不在于语言。小弟只是最近学习Golang,所以顺带熟练一下语法知识,别无它意。 本系列博客主要介绍...

chapin
2015/01/13
0
0
javascript 设计模式之工厂(Factory)模式

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

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

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

爱学习的逃课君
2014/11/27
0
0
设计模式笔录(二),设计模式有哪些

本人出道5年,学习、编程、再学习、再编程一路走过,只是在笔和纸留下些脚印,实感惭愧。现开始把自己学习到的心得,实践中的体会,一一贴在互联网上,大家互相学习、探讨,寻找一些技术朋友...

方旭
2011/03/31
0
0
【设计模式笔记】(十六)- 代理模式

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

MrTrying
06/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

shell中的函数、shell中的数组、告警系统需求分析

shell中的函数 格式: 格式: function f_name() { command } 函数必须要放在最前面 示例1(用来打印参数) 示例2(用于定义加法) 示例3(用于显示IP) shell中的数组 shell中的数组1 定义数...

Zhouliang6
10分钟前
0
0
用 Scikit-Learn 和 Pandas 学习线性回归

      对于想深入了解线性回归的童鞋,这里给出一个完整的例子,详细学完这个例子,对用scikit-learn来运行线性回归,评估模型不会有什么问题了。 1. 获取数据,定义问题     没有...

wangxuwei
31分钟前
0
0
MAC安装MAVEN

一:下载maven压缩包(Zip或tar可选),解压压缩包 二:打开终端输入:vim ~/.bash_profile(如果找不到该文件新建一个:touch ./bash_profile) 三:输入i 四:输入maven环境变量配置 MAVEN_HO...

WALK_MAN
45分钟前
0
0
33.iptables备份与恢复 firewalld的9个zone以及操作 service的操作

10.19 iptables规则备份和恢复 10.20 firewalld的9个zone 10.21 firewalld关于zone的操作 10.22 firewalld关于service的操作 10.19 iptables规则备份和恢复: ~1. 保存和备份iptables规则 ~2...

王鑫linux
58分钟前
0
0
大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
今天
0
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
今天
2
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
今天
1
0
Java IO类库之BufferedInputStream

一、BufferedInputStream介绍 /** * A <code>BufferedInputStream</code> adds * functionality to another input stream-namely, * the ability to buffer the input and to * sup......

老韭菜
今天
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部