设计模式之策略模式(从掌握规则到规则之上)

一.策略模式

将每一种算法都封装到具有共同接口的独立的类中,是算法本身和使用算法的对象分离开来,解决了多种相似算法情况下,以往if...else编程带来的复杂和难以维护。

1.封装变化。

2.使用接口编程。

该模式中包含的角色及其职责:

1.抽象策略角色:具体策略角色的抽象父类。

2.具体策略角色:包装了具体的算法和行为。

3.环境角色:内部会持有一个抽象角色的引用,给客户端调用。

优点:

1.减少了算法类和使用算法类之间的耦合。(扩展性好)

2.Strategy类的层次为Context定义了一系列可供重用的算法或功能,有助于析出这些算法的共有功能,比如可以把实现同一场景的算法的结果可以析出抽象的结果对象。(抽象复用)

3.简化单元测试,每个算法都有自己的类,可以通过自己的接口单独测试。

4.当不同的行为出现堆砌在同一类中,就难免使用条件判断选择合适的行为,将算法封装在不同的行为类里,消除了条件语句。(避免多重条件判断)

5.策略模式不光可以封装算法,当不同场景需要用不同的业务规则解决时,都可以考虑业务类。它将选择具体实现的职责由客户端转向类策略模式的Context对象。

缺点:

1.策略类会增多。

2.所有策略类都需要对外暴露。

例子:诸葛亮为孙刘联军出的计谋为抽象策略角色,具体的计谋为具体策略角色,战役为环境角色,赤壁之战就是这次具体的战役。

抽象策略角色(诸葛亮的n个计谋):

package strategy;


/**
 * 抽象策略角色 诸葛亮的计谋s
 * @author liucong8
 */
public interface Strategy {

    /**
     * 实现两军可以打仗的方法
     * @param sunLiu 孙刘联军
     * @param caoCao 曹操大军
     * @return 战役结果
     */
    public String fighting(String sunLiu, String caoCao);
}

具体策略角色(诸葛亮n个计谋的具体实现):

计谋一:水攻

package strategy;

/**
 * 策略一:诸葛亮出了水攻的计谋
 * @author liucong8
 */
public class WaterStrategy implements Strategy {

    @Override
    public String fighting(String sunLiu, String caoCao) {
        System.out.println("孙刘联军用水对曹操大军进行攻击。");
        return "曹操大军玩耍的很开心,孙刘很崩溃。";
    }
}

计谋二:火攻

package strategy;

/**
 * 策略二:诸葛亮出了火攻的计谋
 * @author liucong8
 */
public class FireStrategy implements Strategy {

    @Override
    public String fighting(String sunLiu, String caoCao) {
        System.out.println("孙刘联军用火对曹操大军进行攻击。");
        return "火烧赤壁,曹操大败。";
    }
}

计谋三:使用网络喷子

package strategy;

/**
 * 策略三:诸葛亮出了调用喷子的计谋
 * @author liucong8
 */
public class ScoldStrategy implements Strategy {

    @Override
    public String fighting(String sunLiu, String caoCao) {
        System.out.println("孙刘联军使用互联网喷子对曹操大军进行攻击。");
        return "两家互喷,不相上下。";
    }
}

环境角色(具体的战役场景是哪里呢?赤壁?官渡?汉中?):

package strategy;

import com.sun.org.apache.regexp.internal.RE;

/**
 * 到底使用哪种计谋呢?
 * @author liucong8
 */
public class Environment {

    /**
     * 持有对策略类的引用,即计谋列表
     */
    private Strategy strategy;

    public  Environment(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 赤壁之战
     * @param sunLiu  孙刘联军
     * @param caoCao  曹操大军
     * @return 结果
     */
    public String chiBiWar(String sunLiu, String caoCao) {
        return strategy.fighting(sunLiu, caoCao);
    }
}

测试客户端(赤壁之战开打!):

package strategy;

/**
 * 测试客户端 赤壁开打ing
 * @author liucong8
 */
public class StrategyTest {

    public static final String SUNLIU = "孙刘联军";
    public static final String CAOCAO = "曹操大军";

    public static void main(String[] args) {

        /**
         * 传入具体的策略类(决定啦!!!使用火攻!)
         */
        Environment environment = new Environment(new FireStrategy());
        String result = environment.chiBiWar(SUNLIU, CAOCAO);
        /**
         * 赤壁之战的结果
         */
        System.out.println(result);
    }
}

结果:

 任何需求变更都需要成本,如何用最小的成本达到最大的效果就是高手和初学者的区别。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值