前言
其他行為型模式:
1. 意圖
定義一系列的算法径筏,把它們一個個封裝起來灵巧,并且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。
2. 適用性
- 一個類定義了多種行為勋磕,并且這些行為在這個類的操作中以多個條件語句的形式出現(xiàn)。
- 需要使用一個算法的不同變體。
- 算法使用客戶不應(yīng)該知道的數(shù)據(jù)∶氤啵可使用策略模式以避免暴露復(fù)雜的、與算法相關(guān)的數(shù)據(jù)結(jié)構(gòu)憎瘸。
3. 參與者
-
Strategy
—— 定義所有支持的算法的公共接口入篮。 - ConcreteStrategy ——以Strategy接口實現(xiàn)某具體的算法。
-
Context
—— 用一個ConcreteStrategy對象來配置幌甘。
—— 維護一個對Strategy對象的引用潮售。
—— 可定義一個接口來讓Strategy訪問它的數(shù)據(jù)。
4. 效果
優(yōu)點:
1) 相關(guān)算法系列 Strategy類層次為Context定義了一些列的可重用的算法或行為锅风。繼承有助于析取這些算法中的公共功能饲做。
2) 一個替繼承的方法。繼承提供了另一種支持多種算法或行為的方法遏弱。你可以直接生成一個Context類的子類盆均,從而給它以不同的行為。將算法封裝在獨立的Strategy類中使得你可以獨立于其Context改變它漱逸,使他易于切換泪姨、易于理解、易于擴展饰抒。
3) 消除了一些條件語句肮砾。Strategy模式提供了條件語句選擇所需的行為意外的另一種選擇。
缺點:
4) Strategy和Context之間的通信開銷袋坑。無論各個ConcreteStrategy實現(xiàn)的算法那是簡單還是復(fù)雜仗处,它們都共享Strategy定義的接口。因為很可能某些ConcreteStrategy不會都用到所有通過這個接口傳遞給它們的信息枣宫;簡單的ConcreteStrategy可能不使用其中的任何信息婆誓!這就意味著有時Context會創(chuàng)建和初始化一些永遠(yuǎn)不會用到的參數(shù)。如果存在這樣的問題也颤,那么將需要在Strategy和Context之間進(jìn)行緊密的耦合洋幻。
5) 增加了對象的數(shù)目。Strategy增加了一個應(yīng)用中的對象的數(shù)目翅娶。有時你可將Strategy實現(xiàn)為可供各Context共享的無狀態(tài)的對象來減少這一開銷文留。任何其余狀態(tài)都由Context維護。
5. 實例
我們舉個畫家的例子竭沫,現(xiàn)在假設(shè)有一個畫家Painter燥翅,他會畫三種形狀的圖形,分別是正方形蜕提、三角形和圓形森书。那么我們先抽象出Strategy的公共接口ShapeStrategy:
/**
* Description: 形狀Strategy<br>
* Author:Terry<br>
* Date:2018/4/25 下午2:17
*/
public abstract class ShapeStrategy {
public abstract void draw();
}
然后對應(yīng)的ConcreteStrategy有三種實現(xiàn):OvalShape、SquadShape、RectangleShape拄氯。
/**
* Description: 圓形 <br>
* Author:Terry<br>
* Date:2018/4/25 下午2:19
*/
public class OvalShape extends ShapeStrategy {
@Override
public void draw() {
System.out.println("draw an oval !");
}
}
/**
* Description: 正方形 <br>
* Author:Terry<br>
* Date:2018/4/25 下午2:19
*/
public class SquadShape extends ShapeStrategy {
@Override
public void draw() {
System.out.println("draw a squad !");
}
}
/**
* Description: 矩形 <br>
* Author:Terry<br>
* Date:2018/4/25 下午2:19
*/
public class RectangleShape extends ShapeStrategy {
@Override
public void draw() {
System.out.println("draw a rectangle !");
}
}
接下來就是聲明Context來配置ConcreteStrategy躲查,其實就是上面我們所說的Painter:
/**
* Description: 畫家 <br>
* Author:Terry<br>
* Date:2018/4/25 下午2:20
*/
public class Painter {
ShapeStrategy strategy;
public Painter(ShapeStrategy strategy) {
this.strategy = strategy;
}
public void draw() {
strategy.draw();
}
}
然后測試一下:
private static void testStrategy() {
Painter painter = new Painter();
painter.setStrategy(new RectangleShape());
painter.draw();
painter.setStrategy(new OvalShape());
painter.draw();
painter.setStrategy(new SquadShape());
painter.draw();
}
運行輸出結(jié)果如下圖: