小白設計模式:策略模式

定義

策略模式(Strategy),是一種對象行爲模式:定義一系列的算法,將可變的部分封裝起來,使得它們能夠相互替換,讓變化的部分於獨立調用它的客戶而變化,不會致使調用方須要跟着修改。 (這邊的"算法"指的是系統中常常會變的部分,多是超類定義的行爲,或者特徵之類的)算法

主要組成

抽象策略接口(Strategy): 定義同一組算法的公共接口;設計模式

具體策略實現(Concrete Strategy): 實現具體的某種算法;bash

客戶端(Client): 調用者,通常會有策略列表存放各類策略,根據須要選擇不一樣的策略實現功能;微信

UML圖

框架代碼

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();
複製代碼

具體例子

UML圖

代碼

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者分離後能夠去除在各個子類單獨實現算法的重複部分;

缺點

  1. 比起將"可變"與"穩定"部分都放一塊兒來說,類數目會增長比較多(大部分設計模式都會這樣)

應用場景

  1. 許多相同的類,可是僅僅是行爲不一致,就可使用策略模式,將不一樣的行爲抽象接口,實現成各個行爲算法類;
  2. 單個類中,存在許多行爲,可是在某些調用的地方須要使用if來判斷不一樣的行爲,則能夠將這些行爲用策略模式優化;

微信公衆號

相關文章
相關標籤/搜索