在軟件構建過程當中,對於某項任務,經常有穩定的總體操做結構,可是各個子步驟卻有不少改變的需求,或者因爲固有的緣由沒法和任務總體結構同時實現。算法
定義一個算法的骨架,講一些步驟(變化的)延遲到子類中,是的子類能夠複用一個算法的結構(骨架)並從新定義(overwrite)某些特定的步驟設計模式
eg1:不使用Template Method public class TemplateMethod { public boolean stap2() { return false; } public void stap4() { } public void run() { TemplateMethod templateMethod = new TemplateMethod(); Lib lib = new Lib(); try { lib.stap1(); if (templateMethod.stap2()) { lib.stap3(); } else { templateMethod.stap4(); } lib.stap5(); } catch (Exception e) { e.printStackTrace(); } } } class Lib { public void stap1() { } public boolean stap3() { return false; } public void stap5() { } }
弊端:TemplateMethod 要實現
run()、 stap2() 、stap4()
方法,然而run()在此例中屬於比較穩定的模塊,屬於整個算法的骨架。屬於子類調用父類方法(早綁定)ide
eg2:使用Template Method public class TemplateMethod2 extends Lib2 { @Override public boolean stap2() {//變化點 return false; } @Override public void stap5() {//變化點 } public static void main(String[] args) { Lib2 templateMethod2 = new TemplateMethod2(); templateMethod2.run(); } } abstract class Lib2 { public void stap1() { } public abstract boolean stap2();// 聲明爲抽象方法 public boolean stap3() { return false; } public void stap4() { } public abstract void stap5(); // 聲明爲抽象方法 public void run() { //穩定骨架(模板) try { stap1(); if (stap2()) { stap3(); } else { stap4(); } stap5(); } catch (Exception e) { e.printStackTrace(); } } }
優勢:TemplateMethod2 要實現
stap2() 、stap4()
方法,然而run()在此例中屬於比較穩定的模塊,屬於整個算法的骨架已經在父類中實現。屬於父類調用子類方法(晚綁定)。性能
在軟件構建過程當中,某些對象使用個算法可能多種多樣,常常改變,若是將這些算法都編碼到對象中,將會使得對象變得異常複雜;並且有時候支持不是用的算法也是一個性能負擔。測試
定義一系列算法,把它們一個個封裝起來,而且使它們能夠互相替換(變化)。該模式使得算法能夠獨立於使用它的客戶程序(穩定)而變化(擴展、子類化).this
//策略接口 public interface Strategy { //定義的抽象算法方法 來約束具體的算法實現方法 public void algorithmMethod(); } // 具體的策略實現1 class ConcreteStrategy1 implements Strategy { //具體的算法實現 @Override public void algorithmMethod() { System.out.println("ConcreteStrategy1"); } } // 具體的策略實現2 class ConcreteStrategy2 implements Strategy { //具體的算法實現 @Override public void algorithmMethod() { System.out.println("ConcreteStrategy2"); } } //策略上下文 class StrategyContext { private Strategy strategy;//持有一個策略實現的引用 public StrategyContext(Strategy strategy) { //使用構造器注入具體的策略類 this.strategy = strategy; } public void contextMethod() { strategy.algorithmMethod(); //調用策略實現的方法 } } class Client { public static void main(String[] args) { Strategy concreteStrategy1 = new ConcreteStrategy1(); //建立具體測策略實現 StrategyContext strategyContext = new StrategyContext(concreteStrategy1); //在建立策略上下文的同時,將具體的策略實現對象注入到策略上下文當中 strategyContext.contextMethod(); //調用上下文對象的方法來完成對具體策略實現的回調 } }
策略接口角色IStrategy:用來約束一系列具體的策略算法,策略上下文角色ConcreteStrategy使用此策略接口來調用具體的策略所實現的算法。編碼
具體策略實現角色ConcreteStrategy:具體的策略實現,即具體的算法實現。設計
策略上下文角色StrategyContext:策略上下文,負責和具體的策略實現交互,一般策略上下文對象會持有一個真正的策略實現對象,策略上下文還可讓具體的策略實現從其中獲取相關數據,回調策略上下文對象的方法。code
- 策略模式就是把各個平等的具體實現進行抽象、封裝成爲獨立的算法類,而後經過上下文和具體的算法類來進行交互。
- 各個策略算法都是平等的,地位是同樣的,正是因爲各個算法的平等性,因此它們纔是能夠相互替換的。
- 雖然咱們能夠動態的切換各個策略,可是同一時刻只能使用一個策略。
定義對象間的一種一對多(變化)的依賴關係,以便當一個對象(Subject)的狀態發生改變時候,全部依賴於它的對象都等到通知並自動更新server
/** * @author lillcol * 2019/6/13-23:38 */ //被觀察者抽象類 public abstract class Subject { abstract void attack(Observer observer);//添加觀察者 abstract void dettack(Observer observer);//移除觀察者 abstract void notifyObserver();//通知觀察者 abstract void operation();//被觀察者狀態變化 } //被觀察者抽象類 abstract class AbstractSubject extends Subject { private List<Observer> observerList = new ArrayList<>(); //觀察者對象集合 @Override void attack(Observer observer) {//添加觀察者 observerList.add(observer); } @Override void dettack(Observer observer) {//移除觀察者 observerList.remove(observer); } @Override void notifyObserver() { for (Observer observer : observerList) { observer.update(); } } } //被觀察者實現類 class ConcreteSubject extends AbstractSubject { @Override void operation() { System.out.println("ConcreteSubject 要搞事情了"); notifyObserver(); // 通知全部觀察者 } } //觀察者抽象類 abstract class Observer { public String name; abstract void setName(String name);//設置名字 abstract String getName();//獲取名字 abstract void update();//觀察者更新方法 } class ConcreteObserver1 extends Observer{ @Override void setName(String name) { this.name=name; } @Override String getName() { return this.name; } @Override void update() { System.out.println("傘兵一號 ConcreteObserver1 準備就緒"); } } class ConcreteObserver2 extends Observer{ @Override void setName(String name) { this.name=name; } @Override String getName() { return this.name; } @Override void update() { System.out.println("傘兵二號 ConcreteObserver2 準備就緒"); } } //測試案例: class Test{ public static void main(String[] args) { ConcreteSubject concreteSubject = new ConcreteSubject(); ConcreteObserver1 concreteObserver1 = new ConcreteObserver1(); ConcreteObserver2 concreteObserver2 = new ConcreteObserver2(); concreteSubject.attack(concreteObserver1); concreteSubject.attack(concreteObserver2); concreteSubject.operation(); System.out.println("------"); concreteSubject.dettack(concreteObserver1); concreteSubject.operation(); } } //輸出: ConcreteSubject 要搞事情了 傘兵一號 ConcreteObserver1 準備就緒 傘兵二號 ConcreteObserver2 準備就緒 ------ ConcreteSubject 要搞事情了 傘兵二號 ConcreteObserver2 準備就緒
其實就是發佈訂閱模式,發佈者發佈信息,訂閱者獲取信息;
訂閱了就能收到信息,沒訂閱就收不到信息。
參考文檔:李建中-(23種設計模式) 本文爲原創文章,轉在請註明出處!!!!