簡介
在策略模式(Strategy Pattern)中,一個類的行爲或其算法可以在運行時更改。這種類型的設計模式屬於行爲型模式。
在策略模式中,我們創建表示各種策略的對象和一個行爲隨着策略對象改變而改變的 context 對象。策略對象改變 context 對象的執行算法。
策略模式角色
- 環境(Context)角色:持有一個Strategy的引用,最終給客戶端調用。
- 抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現。此角色給出所有的具體策略類所需的接口。
- 具體策略(ConcreteStrategy)角色:包裝了相關的算法或行爲。
例子
比如說常見的會員體系,普通會員,黃金會員,白金會員...
示例代碼
package com.example.strategy;
public interface Member {
void show();
}
package com.example.strategy;
/**
* 普通會員
*/
public class CommonMember implements Member{
@Override
public void show() {
System.out.println("我是普通會員");
}
}
package com.example.strategy;
/**
* 黃金會員
*/
public class GoldMember implements Member{
@Override
public void show() {
System.out.println("我是黃金會員");
}
}
package com.example.strategy;
/**
* 白金會員
*/
public class PlatinaMember implements Member{
@Override
public void show() {
System.out.println("我是白金會員");
}
}
package com.example.strategy;
public class Context {
private Member member;
public Context(Member member) {
this.member = member;
}
public void doAction(){
this.member.show();
}
// 動態替換算法(策略)
public void replaceStrategy(Member member) {
this.member = member;
}
}
package com.example.strategy;
public class Test {
public static void main(String[] args) {
Member commonMember = new CommonMember();
Member goldMember = new GoldMember();
Member platinaMember = new PlatinaMember();
//普通會員
Context context = new Context(commonMember);
context.doAction();
//切換策略類爲黃金會員
context.replaceStrategy(goldMember);
context.doAction();
//切換策略類爲白金會員
context.replaceStrategy(platinaMember);
context.doAction();
}
}
策略模式的優缺點
1、優點
- 對客戶隱藏具體策略(算法)的實現細節,彼此完全獨立。具體策略類實現自同一個接口,他們之間可以自由切換
- 良好的擴展性。增加一種策略,只要實現接口,寫上具體邏輯就可以了。當舊策略不需要時,直接剔除就行。
- 使用策略模式可以避免使用多重條件轉移語句。多重轉移語句不易維護,它把採取哪一種算法或採取哪一種行爲的邏輯與算法或行爲的邏輯混合在一起,統統列在一個多重轉移語句裏面,比使用繼承的辦法還要原始和落後。
2、缺點
- 如果策略增多,策略類的數量就會增加,維護各個策略類會給帶來額外開銷,策略類太多時,消耗更大。
- 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。也就是各個策略需要暴露給客戶端。