策略模式(Strategy),是一種對象行爲模式:定義一系列的算法,將可變的部分封裝起來,使得它們能夠相互替換,讓變化的部分於獨立調用它的客戶而變化,不會致使調用方須要跟着修改。 (這邊的"算法"指的是系統中常常會變的部分,多是超類定義的行爲,或者特徵之類的)算法
抽象策略接口(Strategy): 定義同一組算法的公共接口;設計模式
具體策略實現(Concrete Strategy): 實現具體的某種算法;bash
客戶端(Client): 調用者,通常會有策略列表存放各類策略,根據須要選擇不一樣的策略實現功能;微信
Strategy:框架
public interface Strategy {
void AlgorithmInterface();
}
複製代碼
Concrete Strategy:ide
public class ConcreteStrategyA {
@Override
public void AlgorithmInterface(){
//策略A的行爲
}
}
public class ConcreteStrategyB {
@Override
public void AlgorithmInterface(){
//策略B的行爲
}
}
複製代碼
Client:工具
Strategy strategy = new ConcreteStrategyA();
//Strategy strategy = new ConcreteStrategyB();
//執行處無論理策略具體實現細節
strategy.AlgorithmInterface();
複製代碼
Vehicle(Strategy策略模塊):優化
/**
* 交通工具
*
*/
public interface Vehicle {
//使用指定交通工具出發,不關心該工具的操做細節
String go();
}
複製代碼
Car:ui
public class Car implements Vehicle{
@Override
public String go() {
return "開小汽車前往目的地";
}
}
複製代碼
Bilk:this
public class Bilk implements Vehicle{
@Override
public String go() {
return "騎自行車前往目的地";
}
}
複製代碼
Plane:
public class Plane implements Vehicle{
@Override
public String go() {
return "乘坐飛機前往目的地";
}
}
複製代碼
PayMent(Strategy策略模塊):
/**
* 支付方式
*
*/
public interface PayMent {
//不關心支付方式的操做流程,只關心付款結果
String cost();
}
複製代碼
AliPay:
public class AliPay implements PayMent{
@Override
public String cost() {
return "使用支付寶流程付款";
}
}
複製代碼
WeChat:
public class WeChat implements PayMent{
@Override
public String cost() {
return "使用微信流程付款";
}
}
複製代碼
Crash:
public class Crash implements PayMent{
@Override
public String cost() {
return "使用現金流程付款";
}
}
複製代碼
穩定部分TravelPlan(使用各類策略的地方): TravelPlan:
public abstract class TravelPlan {
//可變的策略模塊
Vehicle vehicle;
PayMent payMent;
//公共穩定的操做接口
public void setVehicle(Vehicle vehicle) {
this.vehicle = vehicle;
}
public void setPayMent(PayMent payMent) {
this.payMent = payMent;
}
public void go() {
System.out.println((getGoTime() + payMent.cost() + vehicle.go() + getDestination()));
}
public abstract String getDestination();
public abstract String getGoTime();
}
複製代碼
BeijingTravelPlan:
public class BeijingTravelPlan extends TravelPlan{
@Override
public String getDestination() {
return "北京";
}
@Override
public String getGoTime() {
return "2018.11.12.09:00";
}
}
複製代碼
TaiWanTravelPlan:
public class TaiWanTravelPlan extends TravelPlan{
@Override
public String getDestination() {
return "臺灣";
}
@Override
public String getGoTime() {
return "2018.11.13.10:00";
}
}
複製代碼
簡單使用:
//定義北京旅遊計劃
TravelPlan travelPlan = new BeijingTravelPlan();
travelPlan.setPayMent(new WeChat());
travelPlan.setVehicle(new Car());
travelPlan.go();
//告白出行交通工具和付款方式
travelPlan.setPayMent(new Crash());
travelPlan.setVehicle(new Bilk());
travelPlan.go();
日誌輸出:
2018.11.12.09:00使用微信流程付款開小汽車前往目的地北京
2018.11.12.09:00使用現金流程付款騎自行車前往目的地北京
複製代碼
未將可變部分獨立出來,即不存在Vehicle和PayMent這2個算法模塊,則對於TravePlane繼承體系可能爲:
public abstract class TravelPlan {
String vehicleType;
String payMentType;
public void setVehicle(String vehicle) {
this.vehicleType = vehicle;
}
public void setPayMent(String payMent) {
this.payMentType = payMent;
}
public void go() {
System.out.println((getGoTime() + payMentCost() + vehicleGo() + getDestination()));
}
//存在一大堆條件判斷
public String vehicleGo () {
switch (vehicleType) {
case "Car":
return "開小汽車前往目的地";
case "Bilk":
return "騎自行車前往目的地";
case "Plane":
return "乘坐飛機前往目的地";
default:
return null;
}
}
//存在一大堆條件判斷
public String payMentCost () {
switch (vehicleType) {
case "AliPay":
return "使用支付寶流程付款";
case "WeChat":
return "使用微信流程付款";
case "Crash":
return "使用現金流程付款";
default:
return null;
}
}
public abstract String getDestination();
public abstract String getGoTime();
}
複製代碼
常常會由於業務而發生修改擴展的部分都堆在了相對穩定的部分,沒有面向接口經過組合的方式,後續修改vehicle和PayMent部分可能會不經意點影響到了其它功能點。
1.策略模式封裝了可變部分,使得"可變"部分獨立於"穩定"部分,在常常性的增長修改"可變"部分過程不須要動到"穩定"部分,可用於取代將所有行爲封裝到超類而後由每一個子類都實現一遍的純繼承方式;
2.當算法種類多的時候,避免了一系列的條件判斷,代碼更簡潔;
3.不一樣算法實現同一接口,能夠互相替換,不須要硬編碼到調用處;
4.2者分離後能夠去除在各個子類單獨實現算法的重複部分;