策略模式浅谈

一 什么是策略?策略模式的概念?

  策略模式--乍一听名字感觉摸不着头脑,要理解这个模式首先就得理解什么是策略?

  百度百科中解释:一般是指:1. 可以实现目标的方案集合;2. 根据形势发展而制定的行动方针和斗争方法;3. 有斗争艺术,能注意方式方法。

  因此我们可以把策略理解成根据事情的发展或者变化,想出的对策。这里面很重要的两个词 变化对策。

   我们来看看策略模式的定义

策略模式:将容易变化的方法(算法)封装起来形成一个方法库(算法簇),这里不同的方法可以互相替换,让方法的变化独立于使用方法的主体。

   这么说还是有点抽象。这里可以先有这么一个概念,通过下面的例子。回头再来看这个概念,印象就更深刻了

二 策略模式-案例学习

     案例中涉及到的人物,关系,行为如下

  人物:飞机,直升飞机,配气式飞机,无人机,飞机模型

     关系:飞机是其他所有类型飞机的父类型。

     行为:飞机起飞,飞机滑行,显示飞机外观

 

 从上面的关系中,我们可以看出来,所有的飞机都具备滑行行为(包括飞机模型),但不是所有的飞机都会飞行,即使会飞行的飞机,飞行的方式也不一定相同。

我们来看看不使用策略模式的设计方案

   设计方案一  继承

   设计Plane为抽象类,包括一个默认的fly方法 和run方法。所有其他飞机继承Plane并根据需要是否重写fly方法。一旦重写fly方法就破坏了里氏替换设计原则(即子类可以在任何时候替换父类),而且即便是没有飞行功能的飞机模型,也要重写fly方法。很显然是一个糟糕的设计。

   类图如下所示

   设计方案二   接口

   设计Plane为抽象类,包括默认的滑行方法run。设计一个Fly接口,包含抽象方法fly.

   每种飞机从Plane中继承并实现fly方法。乍一看这种方法很好,

   但是每个具备飞行行为的飞机都得重写一个fly方法,这使得fly方法无法重用。代码严重冗余。类图如下所示

 

   既然以上两种方案都不合适,那么我们来看看策略模式是如何做到优雅,松散耦合易扩展 的设计

  设计方案三   策略模式

   既然重写fly方法不合适,干脆就把fly方法单拿出来,抽象成一个飞行类,跟飞机彻底解耦。飞机只是在准备飞行的时候将飞行行为委托给飞行类,具体的飞行行为有飞行类来完成。这么说有点抽象,我们来看看如何实现。

   首先飞机包含一个行为滑行行为run。和一个抽象方法display,以及一个飞行行为performFly(),这个performFly并不由飞机自己实现,飞机将持有Fly类引用,将飞行行为托管给飞行类中的fly方法来执行。这样飞行行为就和飞机彻底解耦,而且我们要面向接口编程,因此这里我们依赖的都是抽象类或者接口,方便扩展与维护。下面我们先看看具体的类图

 

三 策略模式-代码实现

第一步 定义抽象类Plane 和 飞行类接口Fly

public abstract class Plane {
    
    public Fly fly ;

    public void run(){
        System.out.println(" i am running");
    }
    
    public void performFly(){
        fly.fly();
    }
    
    public abstract void display();
}
public interface Fly {
    void fly();
}

第二步 定义具体的飞行类,实现Fly接口

//使用火箭飞行
public
class FlyWithRock implements Fly { @Override public void fly() { System.out.println("I can fly with rock"); } }
//使用旋翼飞行
public
class FlyWithRotor implements Fly { @Override public void fly() { System.out.println("I fly with wing"); } }
//不能飞行
public
class FlyWithNoway implements Fly { @Override public void fly() { System.out.println("I can not fly"); } }

 

第三步 定义具体的plane,继承自抽象类Plane

//战斗机
public
class FighterPlane extends Plane { @Override public void display() { System.out.println("i am a fighter plane"); } public FighterPlane() { fly = new FlyWithRock(); } }
//客机
public
class AircraftPlane extends Plane { @Override public void display() { System.out.println("i am a aircraft plane"); } public AircraftPlane() { fly = new FlyWithRotor(); } }
//模型飞机
public
class ModelPlane extends Plane { public ModelPlane() { fly = new FlyWithNoway(); } @Override public void display() { System.out.println("i am a model plane"); } }

第四步 测试

public class Test {

    public static void main(String[] args) {
        Plane blackDuck = new FighterPlane();
        Plane whiteDuck = new ModelPlane();
        Plane rubberDuck = new AircraftPlane();
        blackDuck.display();
        blackDuck.performFly();
        System.out.println("--------------------");
        
        whiteDuck.display();
        whiteDuck.performFly();
        System.out.println("--------------------");
        
        rubberDuck.display();
        rubberDuck.performFly();
    }
}

结果

i am a fighter plane
I can fly with rock
--------------------
i am a model plane
I can not fly
--------------------
i am a aircraft plane
I fly with rotor

 

四 策略模式-总结

策略模式中涉及到OO设计原则有:

  面向接口编程,不针对实现编程;

  多有组合,少用继承;

  封装变化;

再一次给出策略模式定义

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

 

注:初次编写博客,如有遗漏或者理解错误,请海涵并指出。博主再次谢过!

参考:Head First 设计模式;

posted on 2016-08-27 16:00  Jerry迎风  阅读(340)  评论(0编辑  收藏  举报

导航