在Head First - Design Pattern 一書, 第一章介紹的就是 Strategy Pattern. 在這裡首先以一個 Duck 類別開始進行說明. 在進行演進過程首先碰到當我們需要對 Duck 擴充使之具有 fly 的行為 (或函式) 時, 第一個我們直覺得就會在父類直接添加該 fly 的行為, 但這個動作卻造成所有 Duck 的子類都有 fly 的行為 (就連 DecoyDuck 都可以 fly =="), 似乎不太合理, 因此接下來便引進了 Strategy Pattern 並將 fly 與 接下來的 quack 行為從父類解偶合出來另外兩個介面 FlyBehavior 與 QuackBehavior. 而不同的 fly 與 quack 行為則實現這兩個介面進行客製化的實作. 而在整個文章有提到一些設計原則說明如下 :
Design Principle :
Strategy Pattern 定義 :
範例說明 :
如同前言提到的, 在Duck 類別需要擴充 fly 與 quack 行為時, 與其直接新增行為在 Duck 類別上, 這裡採用的是使用介面 FlyBehavior 與 QuackBehavior 來封裝各種不同的 fly 與 quack 行為 (封裝演算法). 這裡符合設計原則的 : Favor composition over inheritance. 實際的UML 設計圖如下 :
範例代碼 :
這裡並未詳列所有代碼, 全部代碼請參考附件.
* Duck 類別代碼 :
- package hf.dp.ch01;
- import hf.dp.ch01.behavior.FlyBehavior;
- import hf.dp.ch01.behavior.QuackBehavior;
- public class Duck {
- private String name;
- protected QuackBehavior quack = null;
- protected FlyBehavior fly = null;
- public Duck(String n){
- name = n;
- }
- public void display(){
- System.out.println("\tThis is "+name +" Duck!");
- }
- public void performFly(){
- if(fly!=null) {
- fly.fly();
- }
- }
- public void performQuack(){
- if(quack!=null) {
- quack.Quack();
- }
- }
- public void setName(String name) {
- this.name = name;
- }
- public void setQuack(QuackBehavior quack) {
- this.quack = quack;
- }
- public void setFly(FlyBehavior fly) {
- this.fly = fly;
- }
- }
- package hf.dp.ch01.behavior;
- public interface QuackBehavior {
- public void Quack();
- }
- package hf.dp.ch01.behavior;
- public interface FlyBehavior {
- public void fly();
- }
- package hf.dp.ch01;
- import hf.dp.ch01.behavior.FlyWithWings;
- import hf.dp.ch01.behavior.Quack;
- public class RedHeadDuck extends Duck{
- public RedHeadDuck(String n) {
- super(n);
- quack = new Quack();
- fly = new FlyWithWings();
- }
- }
- package hf.dp.ch01;
- import hf.dp.ch01.behavior.*;
- public class Main {
- public static void main(String args[]) {
- Duck duck1 = new RubberDuck("Rubber Duck");
- duck1.display();
- duck1.performFly();
- duck1.performQuack();
- duck1 = new DecoyDuck("Decoy Duck");
- duck1.display();
- duck1.performFly();
- duck1.performQuack();
- duck1 = new RedHeadDuck("Red Head Duck");
- duck1.display();
- duck1.performFly();
- duck1.performQuack();
- /*Dynamically change behavior of duck*/
- duck1.setFly(new FlyWithNoWing());
- duck1.setQuack(new MuteQuack());
- duck1.display();
- duck1.performFly();
- duck1.performQuack();
- }
- }
補充說明 :
* Strategy Pattern from Wiki :
* Design Patterns 第三炮 : 實作Strategy Pattern,讓元件像USB一般隨插即用!(網路文章)
沒有留言:
張貼留言