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

刚刚开始学习,使用一个书里简单的小例子帮助记忆。

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

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

主类
//完全解耦,只关联了接口,没有任何实例化,靠子类去实现
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再代理一个出生地方法)再生成别的类即可,不影响现有的方法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值