现在我们有一个虚基类-鸭子(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. 二十四种设计模式:责任链模式(Chain of Responsibility Pattern)

    责任链模式(Chain of Responsibility Pattern) 介绍为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求.将这些对象连成一条链,并沿着这条链传递该请求,直 ...

  2. 宝洁的Pvp

    1.公司宗旨(Purpose) 我们生产和提供更佳品质及价值的产品,以改善全球消费者的生活.作为回报,我们将会获得领先的市场销售地位和利润增长,从而令我们的员工.我们的股东以及我们的生活.工作所处的社 ...

  3. hibernate 双向一对多关系(Annotation mappedBy注解理解)

    1.@mappedBy 属性简单理解为设定为主表(OneToMany方)(这只是我个人理解,上面文章中也有提到过) 所以另一端(ManyToOne)则需要设置外键@JoinColumn(name=&q ...

  4. Cannot find class for bean with name service

    Cannot find class [com.jx.p2p.service.impl.LazyInvestServiceImpl] for bean with name 'service' defin ...

  5. MySQL 使用mysqld_multi部署单机多实例详细过程 (转)

    随着硬件层面的发展,linux系统多核已经是普通趋势,而mysql是单进程多线程,所以先天上对多进程的利用不是很高,虽然 5.6版本已经在这方面改进很多,但是也没有达到100%,所以为了充分的利用系统 ...

  6. WCF学习心得------(六)数据协定

    --前言 最近各种事忙的把之前的WCF学习给耽误了一些,今天抽时间把之前的学习内容给总结了一下,因为知识点比较细碎没有做太多的练习示例,只是对其中关键的知识点做了总结,希望可以对大家有所帮助. 第六章 ...

  7. spring-boot支持双数据源mysql+mongo

    这里,首先想说的是,现在的web应用,处理的数据对象,有结构化的,也有非结构化的.同时存在.但是在spring-boot操作数据库的时候,若是在properties文件中配置数据源的信息,通过默认配置 ...

  8. mysql frm的恢复,data里只有frm文件的恢复

    mysql frm的恢复,data里只有frm文件的恢复 mysql frm的恢复,data里只有frm文件的恢复,换了系统,装了windows2003,重装最新5.4版的mysql,把原来的一个数据 ...

  9. .NET RSACryptoServiceProvider PEM + DER Support

    http://www.christian-etter.de/?p=771 In .NET, RSACryptoServiceProvider greatly simplifies common tas ...

  10. C# WebApi 上传文件

    本文转载自:http://www.cnblogs.com/zj1111184556/p/3494502.html public class FileUploadController : ApiCont ...