策略模式

工作忙完一些,刚好有空,就准备继续写一下设计模式的学习总结。

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

先举个代码的例子(举例比较渣渣请原谅)

1、定义一个水果抽象类Fruit

package head_first.strategy.self;

public abstract class Fruit {
    GrowUp grow; //长大的行为
    Plant plant; //种植的行为

    /**
     * 水果的通用方法
     */
    public void canBeEat(){
        System.out.println("I can be eat!");
    }

    public abstract void display(); //子类实现各种水果的特征

    /**
     * 引入长大的实现类,其目的是为了实现在运行过程中可以改变长大的行为
     * @param grow
     */
    public void setGrowUp(GrowUp grow){
        this.grow = grow;
    }
    /**
     * 同上
     * @param plant
     */
    public void setPlant(Plant plant){
        this.plant = plant;
    }

    public void performGrow(){
        grow.growUp();
    }

    public void perfromPlant(){
        plant.plant();
    }
}

GrowUp(长大)和Plant(种植)是水果行为两个抽象(接口),代码为:

package head_first.strategy.self;

public interface Plant {
    public void plant();
}
package head_first.strategy.self;

public interface GrowUp {
    public void growUp();
}

实现了一个具体水果类Apple

package head_first.strategy.self;

public class Apple extends Fruit {

    public Apple(){
        //实现了苹果的两个特殊行为
        grow = new SlowGrowUp();
        plant = new DeepPlant();
    }

    public void display() {
        System.out.println("I am a apple!");
    }

}

和草莓具体类

package head_first.strategy.self;

public class Strawberry extends Fruit {

    public Strawberry() {
        // 实现了草莓的两个特殊行为
        grow = new QuickGrowUp();
        plant = new SimplePlant();
    }

    public void display() {
        System.out.println("I am strawberry");
    }
}

接下来是水果的两种行为长大和种植的具体类:

package head_first.strategy.self;

public class SlowGrowUp implements GrowUp {

    public void growUp() {
        System.out.println("grow up slow");
    }

}

package head_first.strategy.self;

public class QuickGrowUp implements GrowUp {

    public void growUp() {
        System.out.println("grow up quick");
    }

}

package head_first.strategy.self;

public class SimplePlant implements Plant {

    public void plant() {
        System.out.println("Simple plant!");
    }

}

package head_first.strategy.self;

public class DeepPlant implements Plant {

    public void plant() {
        System.out.println("Deep plant!");
    }

}

另外定义一个奔跑的行为(成为食人果啦,哈哈~~)RunPlant :

package head_first.strategy.self;

public class RunPlant implements Plant {

    public void plant() {
        System.out.println("I am a runing fruit!!!");
    }

}

最后是测试类

package head_first.strategy.self;

public class FruitTest {
    public static void main(String[] args) {
    //apple的正常行为
        Apple apple = new Apple();
        apple.performGrow();
        apple.perfromPlant();

        Strawberry straw = new Strawberry();
        straw.perfromPlant();
        //把草莓的种植行为在运行时动态改为喷跑的行为
        straw.setPlant(new RunPlant());
        straw.perfromPlant();
    }
}

测试类输出的结果:
grow up slow
Deep plant!
Simple plant!
I am a runing fruit!!!

例子大概就是这样了。
Fruit抽象类定义了水果的抽象,canBeEat()方法是水果的通用方法,把实现写在Fruit类中,也可以加上final使其避免被子类覆盖。
GrowUp和Plant是对水果的两个可以变化的行为的封装,这样水果类获取的是行为的抽象引用,是针对抽象的编程,可以使水果类与起行为的实现解耦和了,更利于其扩展。
display()方法在Fruit中定义为抽象方法,在各个子类中自己实现自己的独特外貌。
setGrowUp(GrowUp grow)和setPlant(Plant plant)方法提供了运行中动态改变水果行为的能力。也是对行为实现解耦的一种体现。

在设计模式的学习中可以隐藏着许多代码设计原则:

1、封装变化。
上面水果的长大和种植的行为根据不同水果是变化的,所以我们把它封装成抽象,有利于解耦和扩展。

2、多用组合,少用继承。
使用组合建立系统具有很大的弹性,不仅可以将算法族封装成类,更可以在运行时动态的改变行为,只要这些行为都符合定义接口的标准即可。Fruit类中GrowUp和Plant就是组合。

3、针对接口编程,不针对实现编程
针对接口编程后,客户就不需要知道实现的具体细节了,完成了解耦。

对于策略模式就差不多这样吧,有很多没有讲清楚的地方,跟大家互相学习。培养设计模式的思维方式。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值