设计模式(1)—策略模式

0.什么是设计模式?
我们经常使用被人设计好的库和框架,利用他们的API(Application Programming Interface)编写我们的程序,但是我们得把它们“组合”起来。像小孩搭积木一样,建成自己的大厦。其中你用到的“方式”,都是事先存在你脑海中的,这些“方式”都是抽象的,并不是一块块具体的积木。并且,你在搭建的过程中,希望搭建成的玩具简洁,美观,安全,可扩展性强…等等,都是基于你脑海中的“方式”而完成的。这些“方式”.是你在搭建过程中,所经历的成功,失败和借鉴别人的大厦得来的。这些“方式”就称为设计模式。
设计模式比库的等级更高,它将告诉我们如何组织类和对象解决问题。当然,在java优秀的类和库中,也用到了设计模式,这就是源码优秀的原因。这些优秀的设计模式被记录下来,从而知道我们的思想。
为什么一再强调脑海中呢? 当然需要,首先你的脑海中要有基本的模式,才能在实现过程中写出好的设计。
1.什么是策略模式?
OO即(Object Oriented)面向对象。了解过高级语言的同学都知道,OOP(Object Oriented Programming)即面向对象编程,是重头戏。它的特征包括抽象,封装,继承,多态。
策略模式——定义算法族,分别封装起来,让它们之间可以互相独立替换,此模式让算法的变化独立于使用算法的客户。

乍一看非常晦涩难懂,待我们举一个小栗子,大家就会明白了

首先我们要了解几个必要的原则:
(0)封装变化:找出程序中会变化的方面,然后将其和固定不变的方面相分离。
(1)多用组合(combination),少用继承
(2)针对接口编程,不针对实现编程。
这3个原则非常管用,将贯穿我们整个设计模式的学习过程当中。

下面开始最精彩的部分,你将体验到设计模式的魅力。
先从简单的一个实现开始,公司要求你做一个鸭子系统。鸭子我们都知道,一边游泳,一边呱呱叫。同时按特性还分为各种的鸭子,比如红头鸭子,绿头鸭子。按材料分:真鸭子,橡皮鸭(不会飞,吱吱叫),木头鸭子(不会飞,不会叫)
这并不难
现在我们要让鸭子会飞 ,“理所当然”我们将在鸭子类中添加代码:
这里写图片描述

继承了鸭子类的橡皮鸭有个小功能“吱吱叫”(这不难,复写父类即可),但是随之而来的问题出现了:橡皮鸭也飞了起来!

同时,如果有木头鸭子。继承了鸭子类的木头鸭也具备了 “飞”和“叫”的功能!这是完全错误的。

作为一个优秀的OO程序猿,这也不难:我们继续复写!

当有了第四种鸭子(不会飞,会叫),复写!
第五种鸭子(会飞,不会叫),复写!
第六种…第七种….
这样写至少会带来几个问题:
A.代码在多个子类中重复
B.改变父类,造成其他鸭子不要的改变(比如木鸭子不要飞)

所以我们带来了一个原则来拯救你:分开变化和不会变化的部分:

我们在利用第二个原则:针对接口编程

如:我们用Flyable和Quackable接口

扫描二维码关注公众号,回复: 4231083 查看本文章

紧接着我们实现这两个接口:这里写图片描述
这里写图片描述

现在,父类鸭子将飞行和叫动作“委托”(delegate)别人处理,而不是在父类中定义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 duck float,even ddecoys!");
    }
}
//定义FlyBehavior 接口
public interface FlyBehavior{
    public void fly();

}
//实现FlyBehavior接口
public class FlyNoWay implements FlyBehavior {
    public void fly() {
        System.out.println("I cannot fly");
    }
}
public class FlyWithWings implements FlyBehavior {
    public void fly() {
        System.out.println("I am flying!");

    }
}
//定义QuackBehavior接口
public interface QuackBehavior {
    public void quack();
}
//实现QuackBehavior接口
public class Quack  implements QuackBehavior {
    public void quack() {
    System.out.println("Quack");
}
}

public class MuteQuack implements QuackBehavior{

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

     public void quack() {
        System.out.println("Squak");
    }
}
//公司让你创建的鸭子
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 class MiniDuckSimulator{

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

    }
}

//输出结果
Quack
I am flying!

另外,我们还可以动态设定行为,在鸭子运行时的行为也可以改变。这也是最开始的继承方法中所没有的。
在Duck类中,加入两个新方法:

public void setFlyBehavior(FlyBehavior fb)
{   
    flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb)
{   
        qucakBehavior = qb;
}
// 新建一个鸭子
public class MallardDuck  extends Duck{
         public MallardDuck () {
             quackBehavior = new Quack();
             flyBehavior = new FlyWithWings();

         }
public void display(){
    System.out.println("I am a model duck");
     }
}
//实现FlyBehavior接口
public class FlyRocketPowered implements FlyBehavior{
public void fly(){
    System.out.println("i am flying with a rocket!");
}
} 
//测试单元
public class MiniDuckSimulator{

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

//运行结果
I cannot fly
i am flying with a rocket!

猜你喜欢

转载自blog.csdn.net/weixin_37864819/article/details/69660772