策略模式-《Head Firsh 设计模式》第一章

本文要点:

  • 定义
  • 设计原则一:封装变换部分
  • 设计原则二:针对接口编程,而不是针对实现编程。
  • 设计原则三:多用组合,少用继承。
  • 实例:鸭子与行为

策略模式(Strategy Pattern)

一、定义

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

二、设计原则一:封装变换部分

找出可能变换的部分,将其独立,使得某些部分的变化不会影响到其他部分。将这些变换的部分(例如行为)分离出来,组成一类。

三、设计原则二:针对接口编程,而不是针对实现编程。

用行为类去实现行为接口,而不是具体子类去实现行为接口。

针对接口编程本质是针对超类编程。

关键在于利用多态,可以对超类编程,在执行时根据具体情况执行行为。

四、实例:鸭子类和行为类

1. 鸭子类

Duke抽象父类,所有的鸭子继承自父类,在子类里面实现具体特性,并且设置行为。

public abstract class Duke {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public void setFly(FlyBehavior fly) {
        flyBehavior = fly;
    }
    public void setQuack(QuackBehavior quack) {
        quackBehavior = quack;
    }
    public void performFly() {
        flyBehavior.fly();
    }
    public void performQuack() {
        quackBehavior.quack();
    }

    public abstract String getDescription();
}
//黑色鸭子(用翅膀飞,会叫)
public class BlackDuck extends Duke{
    String color = "black";
    public BlackDuck() {
        flyBehavior = new FlyWithWings();
        quackBehavior = new QuackCry();
    }
    public String getDescription() {
        return color+" "+flyBehavior.getDescription()+" "+quackBehavior.getDescription();
    }
}
//木头鸭子(不会飞,吱吱叫)
public class WoodDuck extends Duke{
    String color = "yellow";
    public WoodDuck() {
        flyBehavior = new FlyNoWay();
        quackBehavior = new QuackZhiZhi();
    }
    public String getDescription() {
        return color+" "+flyBehavior.getDescription()+" "+quackBehavior.getDescription();
    }
}

2.飞行类(行为类-定义中的算法族)

//飞行接口
public interface FlyBehavior {
    public String getDescription();
    public void fly();
}
//具体飞行行为类:不会飞
public class FlyNoWay implements FlyBehavior{
    public String getDescription() {
        return "fly no way";
    }
    public void fly() {
        System.out.println(getDescription());
    }
}
//用翅膀飞
public class FlyWithWings implements FlyBehavior{
    public String getDescription() {
        return "fly with wings";
    }
    public void fly() {
        System.out.println(getDescription());
    }
}

3.鸭叫类

//鸭叫接口
public interface QuackBehavior {
    public String getDescription();
    public void quack();
}
//正常鸭叫
public class QuackCry implements QuackBehavior{
    public String getDescription() {
        return "quack cry";
    }
    public void quack() {
        System.out.println(getDescription());
    }
}
//吱吱叫
public class QuackZhiZhi implements QuackBehavior{
    public String getDescription() {
        return "quack zhizhi";
    }
    public void quack() {
        System.out.println(getDescription());
    }
}

4.测试

public class testDuck {
    public static void main(String[] args) {
        Duke duke = new BlackDuck();
        System.out.println(duke.getDescription());
        duke.performFly();//飞行
        duke.performQuack();//鸭叫

        duke = new WoodDuck();
        System.out.println(duke.getDescription());
        duke.performFly();
        duke.performQuack();
    }
}

执行代码:结果正确

black fly with wings quack cry
fly with wings
quack cry
yellow fly no way quack zhizhi
fly no way
quack zhizhi

5.扩展新的行为

我们上面实现了策略模式,现在来扩展行为体会一下策略模式的便捷。这里扩展一个火箭推进的行为FlyRocketPowered(),实现`FlyBehavior接口:

public class FlyRocketPowered implements FlyBehavior{
    public String getDescription() {
        return "fly with Rocket Power!!!";
    }
    public void fly() {
        System.out.println(getDescription());
    }
}

给木鸭子改装火箭推进装置:

Duke duke = new WoodDuck();
System.out.println(duke.getDescription());
duke.performFly();
duke.performQuack();
duke.setFly(new FlyRocketPowered());//给木鸭子火箭推进器
duke.performFly();

结果:

yellow fly no way quack zhizhi
fly no way
quack zhizhi
fly with Rocket Power!!!

成功的更改为火箭推荐!很方便吧!这就是策略模式更换算法族(本例中是行为类)的特点,便于扩展。

五、设计原则三:多用组合,少用继承。

1.什么是组合

像实例中将两个类组合起来用,这就是组合(Composition)。这种方法和“继承”的区别在于,鸭子的行为不是继承而来,而是和适当的行为对象组合而来的。

2.组合的优点

可复用、可扩展、可维护

3.继承提供行为的缺点

  1. 代码在多个子类中重复
  2. 运行时行为不容易改变
  3. 难以知道所有行为
  4. 牵一发而动全身,造成其他子类不想要的改变。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值