在软件构建过程当中,对于某项任务,经常有稳定的总体操做结构,可是各个子步骤却有不少改变的需求,或者因为固有的缘由没法和任务总体结构同时实现。算法
定义一个算法的骨架,讲一些步骤(变化的)延迟到子类中,是的子类能够复用一个算法的结构(骨架)并从新定义(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种设计模式) 本文为原创文章,转在请注明出处!!!!