开发者模式之—-策略者模式

本文通过具体的交通工具票价计算案例,深入浅出地介绍了策略模式的概念及其在实际开发中的应用。通过对比传统if-else和switch-case的解决方案,展示了策略模式如何有效地降低代码耦合度并提高扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发者模式之—-策略者模式

—序言:本文为《Androdi源码及开发模式》的学习笔记。更详细内容请购买查看该正版书籍。
在开发中,当一个任务有多个解决方案时,最简单的方式就是使用 if-else或者 switch -case来实现。但是如果因为if-else这种方法不会遵守开闭原则,所以耦合性很高,当要继续添加功能时,就要修改原来的代码。

而应对这种情况最好的方案就是使用策略者模式,把各种方案分离开来,让程序客户端根据具体的需求来动态选择不同的策略。
以下为策略者的UML图:
这里写图片描述

下面,我们来一出行时乘坐的交通工具票价计算来分析策略者模式的应用。
以下是最简单的用swtch-case实现的:

  /**
     * author: ZK.
     * date:   On 2016/12/18
    *  用switch-case实现的计算器
     */

    public class NormalCalculator {

        public enum TrafficType {
            BUS, SUBWAY
        }

        private final String NORMAL_TAG = "----normal_tag";

        public void calcutePrice(TrafficType trafficType, int km) {
            switch (trafficType) {
                case BUS:
                    Log.d(NORMAL_TAG, km + "公里,公交车价格为:" + busPrice(km) + "元");
                    break;
                case SUBWAY:
                    Log.d(NORMAL_TAG, km + "公里,地铁价格为:" + subwayBus(km) + "元");
            }
        }

        private int busPrice(int km) {
            if (km < 5) {
                return 3;
            } else if (km > 5 && km < 10) {
                return 5;
            } else {
                return 8;
            }
        }

        private int subwayPrice(int km) {
            if (km < 6) {
                return 3;
        } else if (km > 6 && km < 12) {
            return 5;
        } else {
            return 7;
            }
        }

调用时,只需实例化NormalCalculator ,调用calculate方法就可以了。

 NormalCalculator calculator = new NormalCalculator();                      
 calculator.calcutePrice(NormalCalculator.TrafficType.TAXI,10);

代码看起来非常简单,直接调用calcute方法,传入交通类型和距离便可以得出价格了。但是现在我又有个需求了,现在我要添加计算出租车的价格这个需求,这时有人会说,这很简单嘛,不就再写一个taxi(int km)的方法,然后在calcute的switch里面添加相应的类型计算不就行了么。是的,确实看起来很简单,但我需求不停变化时,就需要不停地在原来的代码上修改,这样耦合性就非常高,很容易变得臃肿而且出错。

  public class NormalCalculator {

        public enum TrafficType {
            BUS, SUBWAY, TAXI
        }
        private final String NORMAL_TAG = "----normal_tag";

        public void calcutePrice(TrafficType trafficType, int km) {
            switch (trafficType) {
                case BUS:
                    Log.d(NORMAL_TAG, km + "公里,公交车价格为:" + busPrice(km) + "元");
                    break;
                case SUBWAY:
                    Log.d(NORMAL_TAG, km + "公里,地铁价格为:" + subwayBus(km) + "元");
                    break;
                case TAXI:
                    Log.d(NORMAL_TAG, km + "公里,的士价格为:" + taxiPrice(km) + "元");
            }
        }

        private int busPrice(int km) {
            if (km < 5) {
                return 3;
            } else if (km > 5 && km < 10) {
                return 5;
            } else {
                return 8;
            }
        }

        private int subwayBus(int km) {
            if (km < 6) {
                return 3;
            } else if (km > 6 && km < 12) {
                return 5;
            } else {
                return 7;
            }
        }
        private int taxiPrice(int km) {
            return km * 2;
        }
    }


好了,下面,大招来了。下面,我们来用策略者模式去实现这方案。
首先写一个计算器的接口,提供一个计算的方法:

    public interface StrategyCalculator {
             int calculate(int km);
        }

好了。你要交通工具的计算方案?你自己去另外创建,你只要实现我这个接口,里面怎样的计算价格你自己实现就好。
公交车,是吗?

public class BusCalculator implements StrategyCalculator {
    @Override
    public int calculate(int km) {
        if (km < 5) {
            return 3;
        } else if (km > 5 && km < 10) {
            return 5;
        } else {
            return 8;
        }
    }
}
地铁又怎样:
public class SubwayCalculator implements StrategyCalculator {
    @Override
    public int calculate(int km) {
        if (km < 6) {
            return 3;
        } else if (km > 6 && km < 12) {
            return 5;
        } else {
            return 7;
        }
    }
}

出租车的需求来了,怕啥?妥妥的new class implement***,稳!

public class TaxiCalculator implements StrategyCalculator {
    @Override
    public int calculate(int km) {
        return km * 2;
    }
}

好了,你要计算交通方式的价格?

StrategyCalculator calculator = new BusCalculator();
calculator.calculate(10);

注意,实例化的是你需要的计算器(BusCalculator),但调用者仍然是接口计算器(StrategyCalculator)。由父接口去调用方法,但具体实现还是由BusCalculator去处理。这样BusCalculator里面的实现就没必要暴露给外面知道,使用者只需调用我这接口的方法就可以了,具体内部自己会处理。点击calculate方法查看内部实现时,看到的只是接口的方法而已。如下:

这里写图片描述

这里写图片描述

从以上可以看到使用策略者模式,各个交通工具的计算器之间都是独立的,相互之间没有关联。当我需要增加一个交通工具是,你也是只需创建一个类实现这接口,重写方法就行了。这样在业务逻辑显得更为直观和简单的儿童诗,扩展也更为方便。

在Android源码中的策略者模式实现:
Android的动画过程中,切换的频率是不一定的,有可能是匀速,有可能是加速。这时动画就需要通过一个时间插值器实现这种效果。这时需求来了,我要匀速,我要加速的。我要时快是慢的,这时和上面的交通工具计算器是不是很类似。
这里写图片描述

示例代码链接:
设计模式Demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值