版權申明】非商業目的可自由轉載
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/88085445
出自:shusheng007
設計模式系列文章:
秒懂Java代理與動態代理模式
秒懂設計模式之建造者模式(Builder Pattern)
秒懂設計模式之工廠方法模式(Factory Method Pattern)
秒懂設計模式之抽象工廠模式(Abstract Factory Pattern)
前言
人在IT江湖飄,不懂設計模式咋裝X?
我們這個社會上的事情大概率都符合八二法則,軟件領域也一樣。例如你學習一門編程語言,工作中常用的類來來回回也就那麼幾十個。那麼多設計模式,最常被人使用的也就那麼幾種,所以我們在做事情的時候應該首先着眼於那20%。
策略模式算是設計模式中簡單而又常用的了。
定義
策略模式定義了一系列的算法,並將每一個算法封裝起來,使他們可以相互替換。
使用場景
當你寫代碼的時候發現一個操作有好多種實現方法,而你需要根據不同的情況使用if-else
等分支結構來確定使用哪種實現方式的時候,想一想這個模式。
如何實現
業務場景
2017年的2月14號,王二狗和牛翠花約好在天津之眼約定終身,二狗打扮一番後準備出發,此時問題來了:是坐公交去呢,還是打滴滴快車呢?天氣看起來也不錯,要不騎共享單車吧,省錢還鍛鍊身體。
對應到編程領域就是:目前有三種策略可以實現一個特定的目的,使用何種策略取決於調用者(客戶端)
普通實現
如果我們正常寫代碼,平時也應該這樣,首先保證把功能正確的實現了,然後慢慢重構,設計模式都是在不斷的重構當中應用的。 王二狗會調用會調用goToTianJinEye()
方法,根據自己的實際情況,選擇某一種出行方式。
public class TrafficFeeCalculator {
public int goToTianJinEye(String way, int distance) {
int trafficFee = 0;
switch (way) {
case "bus":
if (distance < 10)
trafficFee = 4;
else
trafficFee = 6;
break;
case "didi":
if(distance<3)
trafficFee = 8;
else
trafficFee=8+(distance-3)*3;
break;
case "sharedBicyle":
trafficFee = 2;
break;
default:
break;
}
return trafficFee;
}
}
那麼這麼寫有什麼弊端呢?
第一:每一種出行方式的交通花費的計算方式都寫在了TrafficFeeCalculator
類中,這個類承擔的職責較多,違反了單一職責原則。
第二:假如王二狗突然想自己開車去,那就需要修改goToTianJinEye
這個方法了。違反了開閉原則。
使用策略模式
以上的場景非常適合使用策略模式,將多種不同的實現算法封裝,然後客戶端根據不同策略分別調用相應的算法。
第一步:封裝不同的實現算法
首先定義一個策略接口,規定算法的同一操作
public interface CalculateStrategy {
int calculateTrafficFee(int distance);
}
第二步:封裝各個算法
//乘坐公交車算法
public class ByBus implements CalculateStrategy {
@Override
public int calculateTrafficFee(int distance) {
return distance<10?4:6;
}
}
//乘坐滴滴快車算法
public class ByDiDiExpress implements CalculateStrategy {
@Override
public int calculateTrafficFee(int distance) {
return distance<3?8:(8+(distance-3)*3);
}
}
//騎共享單車算法
public class BySharedBicycle implements CalculateStrategy {
@Override
public int calculateTrafficFee(int distance) {
return 2;
}
}
第三步:使用算法
public class TrafficFeeCalculator {
...
public int goToTianJinEye(CalculateStrategy strategy,int distance){
return strategy.calculateTrafficFee(distance);
}
}
第四步:客戶端調用
根據情況,構建相應的算法類實例,傳入計算器計算即可
public static void main(String[] args) {
TrafficFeeCalculator calculator=new TrafficFeeCalculator();
System.out.println(String.format("乘坐公交車到天津之眼的花費爲:%d塊人民幣",
calculator.goToTianJinEye(new ByBus(),10)));
System.out.println(String.format("乘坐滴滴快車到天津之眼的花費爲:%d塊人民幣",
calculator.goToTianJinEye(new ByDiDiExpress(),10)));
System.out.println(String.format("騎共享單車到天津之眼的花費爲:%d塊人民幣",
calculator.goToTianJinEye(new BySharedBicycle(),10)));
}
輸出爲:
乘坐公交車到天津之眼的花費爲:6塊人民幣
乘坐滴滴快車到天津之眼的花費爲:29塊人民幣
騎共享單車到天津之眼的花費爲:2塊人民幣
二狗爲了早點見到自己心愛的牛翠花,最終選擇了滴滴快車,貴是貴了點,但是快!
優缺點
優點:降低了算法類的職責,使各個算法可以獨立變化並互相替換。而且使得增加新的算法變的很容易,降低了對原有系統的侵入,最終使得程序可擴展可維護性增強。
缺點:所有設計模式的通病,類增多了,程序從局部來看變的更復雜了。
總結
是不是感覺講設計模式的文章都有一個特點,使用了設計模式反而比不使用設計模式使程序看起來更加複雜,而不是更加簡單。那是因爲每篇文章的示例都是無實際使用意義的示例代碼,實際情況是程序非常複雜才需要使用到設計模式。一個大型程序是不斷迭代出來的,一開始肯定不長那樣,程序員日常接到一個開發任務也不要過多的想,這個我應該用個什麼設計模式呀?先把功能實現了,然後回頭看看有沒有遵循面向對象編程6大原則,如果沒有想想怎麼改進,然後設計模式就登場了。。。
設計模式值得你刻意練習!