设计模式学习笔记之一:策略模式

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

FlyBehavior

package com.singland.dp.strategy;

public interface FlyBehavior {
    void fly();
}

FlyNoWay

package com.singland.dp.strategy;

public class FlyNoWay implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I cannot fly");

    }
}

FlyWithWing

package com.singland.dp.strategy;

public class FlyWithWing implements FlyBehavior {

    @Override
    public void fly() {
        System.out.println("I can fly");

    }
}

QuackBehavior

package com.singland.dp.strategy;

public interface QuackBehavior {
    void quack();
}

Quack

package com.singland.dp.strategy;

public class Quack implements QuackBehavior {

    @Override
    public void quack() {
        System.out.println("quack");

    }
}

MuteQuack

package com.singland.dp.strategy;

public class MuteQuack implements QuackBehavior {

    @Override
    public void quack() {
        System.out.println("No sound");

    }
}

Duck

package com.singland.dp.strategy;

public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    
    protected void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

    protected void setQuackBehavior(QuackBehavior quackBehavior) {
        this.quackBehavior = quackBehavior;
    }

    protected abstract void swim();
    
    protected abstract void display();
    
    protected void performFly() {
        flyBehavior.fly();
    }
    
    protected void performQuack() {
        quackBehavior.quack();
    }

}

DecoyDuck

package com.singland.dp.strategy;

public class DecoyDuck extends Duck {
    
    @Override
    protected void swim() {
        System.out.println("Decoy duck swim");

    }

    @Override
    protected void display() {
        System.out.println("Decoy duck display");

    }

}

RubberDuck

package com.singland.dp.strategy;

public class RubberDuck extends Duck {

    @Override
    protected void swim() {
        System.out.println("Rubber duck swim");

    }

    @Override
    protected void display() {
        System.out.println("Rubber duck display");

    }

}

MyTest

 

package com.singland.dp.strategy;

import org.junit.Test;

public class MyTest {
    
    @Test
    public void testDecoyDuck() {
        Duck decoyDuck = new DecoyDuck();
        decoyDuck.setFlyBehavior(new FlyNoWay());
        decoyDuck.setQuackBehavior(new MuteQuack());
        decoyDuck.display();
        decoyDuck.swim();
        decoyDuck.performFly();
        decoyDuck.performQuack();
        
        Duck rubberDuck = new RubberDuck();
        rubberDuck.setFlyBehavior(new FlyNoWay());
        rubberDuck.setQuackBehavior(new Quack());
        rubberDuck.display();
        rubberDuck.swim();
        rubberDuck.performFly();
        rubberDuck.performQuack();
    }

}

在这个例子中使用到了OO设计原则中的一条:把可变部分跟非可变部分分离开来并对可变部分进行封装。

所有的鸭子都有自己的形状并且能够游泳,但不是所有的样子都能够叫和飞,所以我们把叫和飞这两个行为跟鸭子本身的显示和游泳的行为分离开来并进行封装,这样FlyBehavior和QuackBehavior的具体实现可以多样化,具体的鸭子可以得到具体的飞和叫的行为,面向接口编程的好处就体现出来了。

posted @ 2016-07-13 13:42  StoneFeng  阅读(521)  评论(0编辑  收藏  举报