策略模式
来源:互联网 发布:linux花屏 卡死 编辑:程序博客网 时间:2024/05/21 03:19
策略模式
策略模式也是23种设计模式之一。
策略模式是指将程序中可变部分抽象分离成一系列的算法,并将每一个算法封装起来,而且使他们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
策略模式一般由下面三部分组成:
1. 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
2. 具体策略角色:包装了相关的算法和行为。
3. 环境角色:持有某一个策略类的引用,客户端调用。
策略模式设计原则:
1. 把程序中需要变化的部分抽离出来,独立于不变的部分。
2. 面向接口编程,而不是面向实现编程,多用组合,少用继承。
(组合 :在类中增加一个私有域,引用另外一个已经有的类的实例,通过调用实例的方法从而获得新的功能)
我们以鸭子(Duck)做一个例子。
鸭子有哪些行为呢?
行为:游泳,飞。
所有的鸭子都会游泳我们是知道的,但是所有的鸭子都会飞嘛?
真鸭子会飞,那假鸭子呢?
答案是否定的,依照我们策略设计模式的原则,我们需要把程序中需要变化的部分抽离出来,也就是要把鸭子会飞的行为抽离出来。
在抽离之前,我们先来把不需要分离的部分写出来。
鸭子都会游泳,是一个共有的行为,那么我们把游泳的行为写进抽象鸭子类(Duck)中。
Duck.java代码:
public abstract class Duck {public void swing(){System.out.println("我会游泳!!!");}public void play(){swing();}}共有的行为写完了,那么我们就来写飞的行为,因为有些鸭子会飞,有些鸭子不会飞,所以飞行行为的实现是不同的。
我们创建一个FlyBehavior的接口,让子类去实现不同的行为。
FlyBehavior.java代码:
public interface FlyBehavior {public void fly();}然后我们再创建两个类来继承这个接口,实现不同的飞行行为。
FlyWithWing.java代码:
public class FlyWithWing implements FlyBehavior{@Overridepublic void fly() {System.out.println("我会飞!!!");}}FlyNoWay.java代码:
public class FlyNoWay implements FlyBehavior{@Overridepublic void fly() {System.out.println("很遗憾,我飞不起来。。。");}}
这下子,我们把鸭子飞的行为也写完了,那么我们是不是需要把它们组合起来呢。
再次申明下组合的概念:
组合 :在类中增加一个私有域,引用另外一个已经有的类的实例,通过调用实例的方法从而获得新的功能。
我们需要在Duck类中增加一个私有域,引用FlyBehavior的实例,通过调用它的fly();方法来获得相应的飞行能力。
我们重新修改下Duck类。
修改后的Duck.java代码:
public abstract class Duck {private FlyBehavior flyBehavior;public void setFlyBehavior(FlyBehavior flyBehavior) {this.flyBehavior = flyBehavior;}public void fly(){flyBehavior.fly();}public void swing(){System.out.println("我会游泳!!!");}public void play(){swing();fly();}}flyBehavior属性就是引用的那个私有域,我们为这个属性写上set方法的原因是为了之后能够更好的根据我们的需求而变化。
在fly();方法里面我们调用了flyBehavior的fly();方法,这样我们通过实例化FlyBehavior接口的不同子类来实现flyBehavior.fly()的动态改变。
接下来我们写一个真鸭子的子类来继承抽象Duck类。
RealDuck.java代码:
public class RealDuck extends Duck{public RealDuck(){super.setFlyBehavior(new FlyWithWing());}}我们把假鸭子的代码也写出来。
RubberDuck.java代码:
public class RubberDuck extends Duck{public RubberDuck(){super.setFlyBehavior(new FlyNoWay());}}这样下来,我们的真鸭子和假鸭子都通过自己的构造方法为flyBehavior属性实例化了不同的飞行行为。
我们用真鸭子为例,来测试下,新建一个DuckTest类。
DuckTest.java代码:
public class DuckTest {public static void main(String[] args){RealDuck realDuck=new RealDuck();realDuck.play();}}控制台输出结果:
我会游泳!!!我会飞!!!
我们不需要知道飞行行为的具体实现,我们只需要根据自己的需求实例化不同的FlyBehavior接口子类就OK了。
通过这个实现,我们让可变的飞行行为独立于鸭子类本身,这样可便于后期的维护和拓展。
比如我们现在想写一只超级鸭子,它具有火箭推动的飞行能力,在我们之前的FlyBehavior接口子类中并没有这个飞行行为。
那么我们只需要重新写一个火箭推动的飞行类即可。继承FlyBehavior接口。
FlyWithRocketPower.java代码:
public class FlyWithRocketPower implements FlyBehavior{@Overridepublic void fly() {System.out.println("我用火箭来推动我飞行!!!");}}火箭推动的飞行行为我们写好了,然后再写一只超级鸭子即可。
SuperDuck.java代码:
public class SuperDuck extends Duck{public SuperDuck() {super.setFlyBehavior(new FlyWithRocketPower());}}我们再来测试一下超级鸭子,修改下测试类就好了。
修改后的DuckTest.java代码:
public class DuckTest {public static void main(String[] args){SuperDuck superDuck=new SuperDuck();superDuck.play();}}控制台输出结果:
我会游泳!!!我用火箭来推动我飞行!!!
这让我们在后期需求发生变化或者要求新的功能时,大大减少我们的代码量,我们只需要实现相应的接口即可。
让我们面向接口编程。
这就是策略模式!
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- 策略模式
- solr5.5基础教程
- vs2008 MFC程序 更改 文本框 控件背景
- 关于JS中oop的一点基础知识复习
- C语言实践之贪吃蛇游戏思路及代码
- 基于CentOS 6.4 搭建 WordPress 个人博客
- 策略模式
- duilib标题栏有文字不能拖动处理方法
- 按钮点击监听
- Mac上IntelliJ Idea运行Java程序时出现红色的警告解决办法-亲测有效
- 关于JSP的C标签之forEach循环分隔符实现
- Service的各种知识点
- Android M 新的运行时权限开发者需要知道的一切
- Genymotion安装和配置idea插件
- light oj 1042 Secret Origins