设计模式1——策略模式

这次阅读HeadFirst这本书的读书笔记,就想把学到的写成博客与之分享, 第一次写博客,如有错误欢迎纠错。

1.1定义

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

1.2引例(模拟鸭子应用)

需求: 系统中会出现很多鸭子,一边游泳,一边呱呱叫


1.2.1 通过超类和继承设计

其他不同的鸭子也像图中的两种鸭子一样,继承Duck超类。
每个鸭子子类负责实现自己的display()方法。
在这里插入图片描述

可以看出鸭子:
共同点:①游泳 ②呱呱叫。
不同点:外表不同。
实现方式:通过继承超类Duck,其中超类中quack()swim()方法都是相同,在超类Duck中进行实现。display()方法不同的鸭子子类实现方式不同,因此将display()方法设计为抽象类。

追加需求:提高竞争力,要求鸭子会飞。


1.2.2 超类增加方法

做法:直接在超类增加fly()方法。
在这里插入图片描述

问题:屏幕上很多橡皮鸭也在飞,不是所有鸭子都会飞。


1.2.3 利用接口解决

做法:将fly和quack动作单独提取出来,做成接口:flyablequackable接口。换句话讲就是将鸭子共同的特点保留在超类,将不同的特点进行提取做成不同的接口。不同鸭子的子类根据需实现相应的接口。
在这里插入图片描述

问题:如果是fly的方式有很多,可以用翅膀,飞行器等等,quack方式也有很多,比如呱呱叫,吱吱叫等等,这样设计会出现大量的代码需要改写。


恰好现在有一种设计原则适用于这个问题。

设计原则:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混合在一起。


1.2.4 设计鸭子的行为

1.分析鸭子的行为
找出变化的和不会变化的行为。可以看出鸭子会变化的行为目前有两个:fly和quack。不会变的行为是swim,所有的鸭子都会游泳。从图4中可以看出,fly和quack行为不单单只有一种,
在这里插入图片描述
2.设计鸭子的行为

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


这次不让鸭子的子类去实现行为的接口,而是用不同的行为类去实现这些接口。
以前是的做法是让超类去实现或者使用接口让子类自行实现,这两种做法都依赖于“实现”。设计没有弹性。
现在的设计不会被“实现”绑死。换句话说,具体的实现都编写在了实现FlyBehavior和quackBehavior的类中。
在这里插入图片描述

1.2.4 总设计

(1)Duck超类变成抽象类,又添加了两个成员变量,FlyBehavior和QuackBehavior两个。
(2)增加4个方法:performFly(),performQuack(),setFlyBehavior()setQuackBehavior()
(3)两个perform方法分别调用接口中的fly()quack()方法。 两个set方法是分别设置两个成员变量FlyBehavior和QuackBehavior。
(5)将display()方法作为抽象方法进行使用。

在这里插入图片描述

(6)其他鸭子的子类通过继承Duck超类,并在构造方法中设置成员变量。以MallardDuck构造方法为例,这样MallardDuck就实现了不会飞,呱呱叫的行为。

	MallardDuck (){
		flyBehavior=new FlyNoWay();
		quackBehavior=new Quack();
	}

图6中的封装飞行行为和封装叫行为都有不同的实现,这就避免了面对“实现”编程,通过组合来编程,这样更加灵活。

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


1.3代码

点击进入github源码地址>>>

(1)Duck 抽象类:

public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

    public Duck() {
    }

    public abstract void display();

    public void performFly() {
        flyBehavior.fly();
    }

    public void performQuack() {
        quackBehavior.quack();
    }

    public void swim() {
        System.out.println("All ducks float,even decoys");
    }

    public void setFlyBehavior(FlyBehavior flyBehavior) {
        this.flyBehavior = flyBehavior;
    }

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

}

(2) 鸭子子类(只写了两个子类实现)

//MallardDuck 子类
public class MallardDuck extends Duck {
    public MallardDuck() {
        quackBehavior = new Quack();
        flyBehavior = new FlyWithWings();
    }

    public void display() {
        System.out.println("I am a real Mallard duck");
    }


    public static void main(String[] args) {
        Duck mallard = new MallardDuck();
        mallard.performFly();
        mallard.performQuack();
    }
}

//ModelDuck 子类
public class ModelDuck extends Duck {

    public ModelDuck(){
        flyBehavior=new FlyNoWay();
        quackBehavior=new Quack();
    }
    public void display() {
        System.out.println("I am a model duck");
    }

    public static void main(String[] args) {
        Duck model =new MallardDuck();
        model.performFly();
        model.setFlyBehavior(new FlyRocketPowered());
        model.performFly();
    }
}

(3) FlyBehavior 接口及行为类

//FlyBehavior 接口
public interface FlyBehavior {
    void fly();
}


public class FlyNoWay implements FlyBehavior {
    public void fly() {
        System.out.println("I can not fly");
    }
}
//添加了一个用火箭飞行的行为
public class FlyRocketPowered implements FlyBehavior {
    public void fly() {
        System.out.println("I am flying with a rocket");
    }
}

public class FlyWithWings implements FlyBehavior {
    public void fly() {
        System.out.println("I am flying");
    }
}

(4)QuackBehavior接口及行为类

//QuackBehavior接口
public interface QuackBehavior {
    void quack();
}

public class MuteQuack implements QuackBehavior {
    public void quack() {
        System.out.println("<< Silence>>");
    }
}


public class Quack implements QuackBehavior {
    public void quack() {
        System.out.println("Quack!");
    }
}


public class Squeak implements QuackBehavior {
    public void quack() {
        System.out.println("Squeak");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值