您的位置:首页 > 其它

策略模式(参考仿造《Head First设计模式》)

2016-05-21 13:46 453 查看
刚刚开始学习,使用一个书里简单的小例子帮助记忆。

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

我们先来看一个简单的案例

主类

//完全解耦,只关联了接口,没有任何实例化,靠子类去实现
public class Food {
public Eat eatBehavior;     //接口
public void performEat(){  //代理实现接口,测试的时候直接调用该方法即可
eatBehavior.eat();
}
}


子类

public class Noodle extends Food {
public Noodle(){
eatBehavior = new Noodle_imp();  //实例化接口
}
}


接口

public interface Eat {
void eat();
}


实例化接口

public class Noodle_imp implements Eat {
@Override
public void eat() {
System.out.println("吃面条");
}
}


测试

public static void main(String[] args) {
Food f = new Noodle(); //使用多态,noodle子类中有构造方法实例化接口方法
f.performEat();         //调用父类方法,此时已经实例化接口方法
}


输出:

吃面条


这样全面解耦以后,可以起无数个子类来继承主类,只要每个子类内部实例化各个接口方法即可。例如做饭的接口,购买的接口等等,主类只要再起几个代理方法,子类构造方法实例化这些接口即可。

下面就是headFirst里面的一个案例,比较全面,复制到项目里面跑一下就知道精妙之处了。

一、主类

public class Duck {
public FlyBehavior flyBehavior;//飞行行为
public QuackBehavior quackBehavior;//叫声行为
public void swim(){
System.out.println("我会游泳");
}
public void display(){
System.out.println("我是白色的");
}
public void performQuack(){//叫声代理方法
quackBehavior.quack();
}
public void performFly(){//飞行代理方法
flyBehavior.fly();
}
public void setFlyBehavior(FlyBehavior flyBehavior) {//项目中可以动态修改飞行
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}

}


二、行为接口

1、飞行行为接口

public interface FlyBehavior{
void fly();
}


2、叫声行为接口

public interface QuackBehavior {
void quack();
}


三、行为实现

1、不能飞

public class FlyNoWay implements FlyBehavior {

@Override
public void fly() {
System.out.println("不能飞");
}

}


2、可以飞

public class FlyWithings implements FlyBehavior {

@Override
public void fly() {
System.out.println("飞行");
}
}


3、嘎嘎叫

public class Quack implements QuackBehavior{
@Override
public void quack() {
System.out.println("嘎嘎叫");
}
}


4、吱吱叫

public class Squeak implements QuackBehavior {

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


四、子类

public class MalardDuck extends Duck{
public MalardDuck(){
quackBehavior = new Quack();//使用多态,实例化一个“嘎嘎叫”的鸭子
flyBehavior = new FlyWithings();//不会飞
}
@Override
public void display() {
System.out.println("我是绿色的");
}
}


五、测试

public class test {
public static void main(String[] args) {
Duck d = new MalardDuck();
d.performQuack();
d.performFly();
d.swim();
d.display();
}
}


如果有新的鸭子,比如一个模型鸭子,不会叫也不会飞,这个时候只要再写一个类即可。

为了能动态生成模型鸭子,在Duck父类里面加入了set方法

//实现的时候
public class test {
public static void main(String[] args) {
/*Duck d = new MalardDuck();
d.performQuack();
d.performFly();
d.swim();
d.display();*/
Duck d = new ModelDuck();//模型鸭子
d.performQuack();
d.swim();
d.display();
d.setFlyBehavior(new FlyRocketPowered());//飞行模式,需要一个实现接口的方法,该类实现了fly接口的方法
d.performFly();
}
}


控制台输出:

嘎嘎叫
我会游泳
我是模型鸭
我能使用火箭飞行


这样,如果又有新的鸭子,新的方法(比如出生地,模型鸭子没有,则父类Duck再代理一个出生地方法)再生成别的类即可,不影响现有的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: