文档章节

四、设计模式——策略模式

文森特梵高
 文森特梵高
发布于 2015/08/14 02:05
字数 966
阅读 109
收藏 12
点赞 0
评论 0

面向对象的设计方案

产品狗今天跟你说,要做一个“模拟鸭子游戏”,需求如下:

鸭子有共同的功能,比如游泳和叫。

鸭子也有不同的功能,比如有绿头鸭和红头鸭。

所以想到了通过使用OO的方式,将共同的功能放在抽象类Duck中,而不同的用abstract修饰供子类实现。

public abstract class Duck {
	public Duck() {
	}
	public void Quack() {
		System.out.println("~~gaga~~");
	}
	public abstract void display();//不同样子的鸭子,有不同的实现
	public void swim() {
		System.out.println("~~im swim~~");
	}
}
public class GreenHeadDuck extends Duck {//绿头鸭
	@Override
	public void display() {
		System.out.println("**GreenHead**");
	}
}
public class RedHeadDuck extends Duck {//红头鸭
	@Override
	public void display() {
		System.out.println("**RedHead**");
	}
}

通过面向对象的思想,我们实现了复用,完成了需求。


新需求


看看这种设计在增加新功能的时候,其扩展性如何。

新需求:添加会飞的鸭子

public abstract class Duck {
        //...略...
	public void Fly() {
	     System.out.println("~~im fly~~");
	}
}

如果在超类中添加这段代码,那么问题马上就来了,超类中添加的方法对所有之类都生效,而不是所有的鸭子都需要这个功能。

public class GreenHeadDuck extends Duck {
        //...略...
	public void Fly() {
		System.out.println("~~no fly~~");
	}
}

那我们可以覆盖掉不会飞的鸭子的fly方法,不就可以了吗~~~

问题又来了,如果有10种不会飞的鸭子,岂不是要重复做10次重复性的工作?

那可不可以把超类中的fly方法弄成abstract呢?

这样所有的之类不就都要实现fly方法吗~如果50种鸭子,那就需要实现50次!

如果又有新需求,比如石头鸭子,既不会飞也不会叫 ,如何实现? +_+

看来上述都不是很好的设计方案。



思路


分析软件设计需要考虑两方面的问题

1)分析项目变化和不变的部分,对于变化的部分,抽象成接口+实现;

2)找到那些功能会根据新需求而变化。

这个模拟鸭子的游戏中,鸭子的叫声和飞行方式会变。



策略模式实现

对飞行和叫分别设计接口,对于不同的叫声和飞行再通过实现的方式完成。

public interface FlyBehavior {
	void fly();
}
public	interface QuackBehavior {
	void quack();
}

这样新增行为变得很简单,只需要实现相同的接口即可。

在鸭子超类中,通过组合抽象的飞行和抽象的叫声,具体的叫和飞交给之类补充。

import com.java.hexter.stimulateduck.flybehavior.FlyBehavior;
import com.java.hexter.stimulateduck.quackbehavior.QuackBehavior;

public abstract class Duck {
	FlyBehavior mFlyBehavior;
	QuackBehavior mQuackBehavior;
	public Duck() {
	}
	public void Fly() {
		mFlyBehavior.fly();
	}
	public void Quack() {
		mQuackBehavior.quack();
	}
	public abstract void display();
	public void SetQuackBehavoir(QuackBehavior qb) {
		mQuackBehavior = qb;
	}
	public void SetFlyBehavoir(FlyBehavior fb) {
		mFlyBehavior = fb;
	}
	public void swim() {
		System.out.println("~~im swim~~");
	}
}

看到没有,抽象超类中没有任何具体的实现类耦合,而是通过接口调用。

里面的fly还是quack函数,都是根据之类mFlyBehavior和mQuackBehavior的不同而不同。

看看绿头鸭以及红头鸭的实现过程。

public class GreenHeadDuck extends Duck {
	public GreenHeadDuck() {
		mFlyBehavior = new GoodFlyBehavior();
		mQuackBehavior = new GaGaQuackBehavior();
	}
	@Override
	public void display() {
		System.out.println("**GreenHead**");
	}
}

public class RedHeadDuck extends Duck {
	public RedHeadDuck() {
		mFlyBehavior = new BadFlyBehavior();
		mQuackBehavior = new GeGeQuackBehavior();
	}
	@Override
	public void display() {
		System.out.println("**RedHead**");
	}
}

很强大,又木有~~~ 脑洞打开的赶脚


策略模式:

行为抽象成接口,并且实现算法族,在超类中放行为接口对象,子类里具体设置行为对象。

原则是分离变化部分,封装接口,基于接口编程各种功能,让行为的实现能单独变化。


© 著作权归作者所有

共有 人打赏支持
文森特梵高
粉丝 2
博文 28
码字总数 15386
作品 0
广州
程序员
Java 设计模式(14) —— 复合模式

一、复合模式 模式常一起使用,组合在一个设计解决方案中 复合模式在一个解决方案中结合两个或多个模式,能解决一般性或一系列的问题 二、示例 本次设计模式讲解中无代码示例,由于复合模式是...

磊_lei
05/26
0
0
C#设计模式(2)——简单工厂模式

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

技术小胖子
2017/11/08
0
0
迈向大牛的重要一步——掌握设计模式

IT职场的小菜经常有这样的疑问: 为什么一个相似的功能,大牛一会儿就搞定,然后悠闲地品着下午茶逛淘宝;而自己加班加点搞到天亮还做不完。 为什么用户提出需求变更后,大牛只需潇洒地敲敲键...

一枚Sir
2015/04/10
0
0
JavaScript设计模式之观察者模式

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

Srtian
05/22
0
0
【设计模式笔记】(十六)- 代理模式

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

MrTrying
06/24
0
0
Java设计模式之抽象工厂模式

抽象工厂模式特点 抽象工厂模式与工厂模式最大的区别是每个单独的产品是一个工厂模式,而多个不同产品交互则是抽象工厂模式,抽象工厂模式通常要运用工厂模式的方法。通常,工厂模式的所有产...

断桥残雪断桥残雪
2015/08/09
0
0
设计模式-抽象工厂模式(C#)

设计模式——抽象工厂模式(JAVA) 在抽象工厂模式中,一个具体工厂可以生产一组相关的具体产品,这样的一组产品成为产品族,产品族中的每一个产品都属于某一个产品继承等等级结构。当系统所...

PXZ6603
06/26
0
0
简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别

转载:原地址http://www.cnblogs.com/zhangchenliang/p/3700820.html 简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别 结合简单示例和UML图,讲解工厂模式简单原理。 一、引子 话说...

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

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

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

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

hlxiong
2014/04/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MyBatis源码解读之延迟加载

1. 目的 本文主要解读MyBatis 延迟加载实现原理 2. 延迟加载如何使用 Setting 参数配置 设置参数 描述 有效值 默认值 lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延...

无忌
9分钟前
0
0
javascript 类变量的实现

代码如下: function echo(){ for(let i=0;i<arguments.length;i++) console.log(arguments[i]);}function extend(o, p){for (prop in p) {o[prop] = p[prop]}retur......

backbye
13分钟前
0
2
编程语言对比分析:Python与Java和JavaScript(图)

编程语言对比分析:Python与Java和JavaScript(图): 凭什么说“Python 太慢,Java 太笨拙,我讨厌 JavaScript”?[图] 编程语言生而为何? 我们人类从原始社会就是用语言表达自己,互相沟通...

原创小博客
21分钟前
0
0
Akka构建Reactive应用《one》

看到这Akka的官网,描述使用java或者scala构建响应式,并发和分布式应用更加简单,听着很高级的样子,下面的小字写着消息驱动,但是在quickstart里面又写容错事件驱动,就是这么钻牛角尖。 ...

woshixin
33分钟前
0
0
ffmpeg源码分析 (四)

io_open 承接上一篇,对于avformat_open_input的分析还差其中非常重要的一步,就是io_open,该函数用于打开FFmpeg的输入输出文件。 在init_input中有这么一句 if ((ret = s->io_open(s, &s-...

街角的小丑
34分钟前
0
0
String,StringBuffer ,StringBuilder的区别

不同点 一、基类不同 StringBuffer、StringBuilder 都继承自AbStractStringBuilder,String 直接继承自 Object 2、底层容器“不同” 虽然底层都是字符数组,但是String的是final修饰的不可变...

不开心的时候不要学习
49分钟前
0
0
nodejs 文件操作

写文件code // 加载文件模块var fs = require("fs");var content = 'Hello World, 你好世界!';//params 文件名,内容,编码,回调fs.writeFile('./hello.txt',content,'utf8',function (er......

yanhl
52分钟前
0
0
SpringBoot mybits 查询为0条数据 但是在Navicat 中可以查询到数据

1.页面请求: 数据库查询: 2018-07-16 17:56:25.054 DEBUG 17312 --- [nio-9010-exec-3] c.s.h.m.C.selectSelective : ==> Preparing: select id, card_number, customer_id, customer_nam......

kuchawyz
今天
0
0
译:Self-Modifying cod 和cacheflush

date: 2014-11-26 09:53 翻译自: http://community.arm.com/groups/processors/blog/2010/02/17/caches-and-self-modifying-code Cache处在CPU核心与内存存储器之间,它给我们的感觉是,它具......

我叫半桶水
今天
0
0
Artificial Intelligence Yourself

TensorFlow是谷歌基于DistBelief进行研发的第二代人工智能学习系统,其命名来源于本身的运行原理。Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算,TensorFlow为张量从流...

孟飞阳
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部