现在我们有一个虚基类-鸭子(abstract Duck). 有真鸭子,野鸭子,橡皮鸭子继承了该类。虚基类有swing方法,毕竟游泳是所有的鸭子都应有的功能。还有一个虚方法display,这个方法在子类中复写,毕竟每种鸭子的信息不一样。

现在我们有新的需求,需要让我们的鸭子会飞。那么我们可以轻松的想到,在Duck虚基类中增加一个fly方法就行了。但实际上,如果真这么做的话,会让所有的鸭子都有该功能。而实际上,橡皮鸭是不能飞的!那么,干脆我们不把fly方法写到基类,而是把fly方法抽象成接口,让需要该功能的类都实现这个接口。这样也会有问题,假如我们有更多种类的鸭子怎么办?我们是不是要为每一个新增的鸭子子类都实现这个接口呢?这样无疑给我们代码增加了很多维护成本,也降低了扩展性。

好的,是时候揭晓答案了。我们抽象出一个FlyBehavior接口,然后将各种飞行的方法抽象成不同的类,让不同的类都实现FlyBehavior借口。然后在我们的Duck虚基类中设置一个FlyBehavior属性,让鸭子具有这种功能。当我们在写子类的时候我们可以动态的决定该子类需要什么样的Fly方法。

代码如下:

FlyBehavior接口:

public interface FlyBehavior
{
void fly();
}

FlyWithWing子类实现FlyBehavior接口。该类代表正常的飞行能力。

public class FlyWithWing implements FlyBehavior
{ public void fly()
{
// TODO Auto-generated method stub
System.out.println("Fly with wing....");
} }

FlyNoWay子类实现FlyBehavior接口。该类代表没有飞行能力。

public class FlyNoWay implements FlyBehavior
{ public void fly()
{
// TODO Auto-generated method stub
System.out.println("Cannot fly.");
//throw new Exception("can not fly");
}
}

FlyWithRocketPower实现FlyBehavior接口。该类代表鸭子装上了火箭引擎的飞行能力。

public class FlyWithRocketPower implements FlyBehavior {

    public void fly()
{
// TODO Auto-generated method stub
System.out.println("Fly with a rocket power on");
} }

Duck虚基类:

public abstract class Duck
{
private FlyBehavior flyBehavior; public Duck()
{} public void fly()
{
this.flyBehavior.fly();
} public void setFlyBehavior(FlyBehavior flyBehavior)
{
this.flyBehavior = flyBehavior;
} public void swing()
{
System.out.println("duck is swinging");
} public abstract void display();
}

RealDuck类,继承了Duck类。真实的鸭子用翅膀飞。

public class RealDuck extends Duck
{
public RealDuck()
{
super.setFlyBehavior(new FlyWithWing());
} @Override
public void display() {
// TODO Auto-generated method stub
System.out.println("This is a real duck");
} }

RubberDuck类,继承了Duck类。橡皮鸭不能飞。

public class RubberDuck extends Duck
{
public RubberDuck()
{
super.setFlyBehavior(new FlyNoWay());
} @Override
public void display()
{
// TODO Auto-generated method stub
System.out.println("This is a rubber duck. it cannot fly nor quack.");
} }

SupperDuck类,继承了Duck类。超级鸭子能用火箭做动力。

public class SuperDuck extends Duck
{
public SuperDuck()
{
super.setFlyBehavior(new FlyWithRocketPower());
}
@Override
public void display()
{
// TODO Auto-generated method stub
System.out.println("This is a super duck. It can fly with rocket power to the moon.");
}
}

main函数,测试方法。实例化各种子类,然后还可以动态设置各个鸭子具有的功能。本例中,橡皮鸭一开始不能飞,但后来将其升级为用火箭做动力的鸭子。

public class DuckSimulator
{
public static void main(String[] args)
{
Duck realDuck = new RealDuck();
realDuck.fly();
realDuck.display();
System.out.println("============================"); RubberDuck rubberDuck = new RubberDuck();
rubberDuck.fly();
rubberDuck.display();
System.out.println("============================"); SuperDuck superDuck = new SuperDuck();
superDuck.fly();
superDuck.display();
System.out.println("============================"); //upgrade rubber duck to rocket power
rubberDuck.setFlyBehavior(new FlyWithRocketPower());
rubberDuck.fly();
}
}

输出结果如下:
Fly with wing....
This is a real duck
============================
Cannot fly.
This is a rubber duck. it cannot fly nor quack.
============================
Fly with a rocket power on
This is a super duck. It can fly with rocket power to the moon.
============================
Fly with a rocket power on

JAVA中的策略模式的更多相关文章

  1. Java中的策略模式,完成一个简单地购物车,两种付款策略实例教程

    策略模式是一种行为模式.用于某一个具体的项目有多个可供选择的算法策略,客户端在其运行时根据不同需求决定使用某一具体算法策略. 策略模式也被称作政策模式.实现过程为,首先定义不同的算法策略,然后客户端把 ...

  2. JAVA中的策略模式strategy

    原文出自:http://ttitfly.iteye.com/blog/136467 1. 以一个算术运算为例,传统做法为: java 代码 package org.common; public cla ...

  3. java中的策略设计模式

    本文主要讲java中的策略模式:一个可以根据不同的传入参数而具有不同行为的方法,就叫策略模式.概念可能有点不好理解,具体看下面代码: import java.util.Arrays; /** * 策略 ...

  4. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  5. 理解javascript中的策略模式

    理解javascript中的策略模式 策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换. 使用策略模式的优点如下: 优点:1. 策略模式利用组合,委托等技术和思想,有效 ...

  6. (转)轻松学,Java 中的代理模式及动态代理

    背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...

  7. 在商城系统中使用设计模式----策略模式之在spring中使用策略模式

    1.前言: 这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式. 2.问题: 在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 c ...

  8. JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

  9. 23中java设计模式(1)-- 策略模式

    近来不太忙,就打算抽空看下源码补充一下知识,当我看了之后我发现看源码的关键是要弄清楚类之家的关系以及为何要这样的关系,否则如果只看具体的代码那不如去学习会儿算法. 于是就打算从设计模式入手,边学习边记 ...

随机推荐

  1. shell流程控制语句

    linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while,until),选择语句(case/select).下面我将通过例子介绍下,各个语句使用方法. 1 ...

  2. OpenJudge计算概论-求平均年龄

    /*============================================== 求平均年龄 总时间限制: 1000ms 内存限制: 65536kB 描述 班上有学生若干名,给出每名学 ...

  3. Storyboard 跳转 和 传值

    因为苹果推 Storyboard 而且 目前来看, Apple Watch 也是用 Storyboard 就知道, 明天应用估计都是 Storyboard 的天下了. (水平有限, 不对之处在所难免, ...

  4. 电脑设置固定ip

  5. ubuntu设置环境变量

    sudo gedit /etc/environment path结尾处追加 路径,如::/opt/EmbedSky/4.3.3/bin source /etc/environment,或者重启电脑?? ...

  6. 【转】ASP.NET MVC 的最佳实践

    [This post is based on a document authored by Ben Grover (a senior developer at Microsoft). It is ou ...

  7. SPOJ #11 Factorial

    Counting trailing 0s of n! It is not very hard to figure out how to count it - simply count how many ...

  8. Python基础教程【读书笔记】 - 2016/6/26

    希望通过博客园持续的更新,分享和记录Python基础知识到高级应用的点点滴滴! 第一波:第6章  抽象 [总览] 介绍函数.参数parameter.作用于scope概念,以及递归概念. [6.1] 函 ...

  9. MySQL瘦身

    解压mysql-x.y.z-win32|64.zip 删除不用的目录:保留bin.data.share三个文件夹 删除bin里的多余文件:保留mysqld.exe.mysqladmin.exe (如果 ...

  10. js setTimeout

    setTimeout用法 //每个0.5秒钟改变字体和背景颜色,字体一闪一闪的效果 var flag = 0; function start(){ var text = document.getEle ...