同步回调callBack 通过B复用,A扩展实现类似模板模式的功能
package com.lf.pattern.callback; public interface ICallback { void methodToCallback(); }
package com.lf.pattern.callback; public class BClass { //可以复用 public void process(ICallback callback) { //...xxx() System.out.println("B begin."); callback.methodToCallback(); //...xxx() System.out.println("B end."); } }
package com.lf.pattern.callback; /** * 同步回调callBack 通过B复用,A扩展实现类似模板模式的功能 */ public class AClass implements ICallback{ public static void main(String[] args) { BClass b = new BClass(); b.process(new ICallback() { //回调对象 @Override public void methodToCallback() { System.out.println("Call back me."); } }); b.process(new AClass()); } //A 定制代码 @Override public void methodToCallback() { System.out.println("Im A duixiang."); } }
模板模式 VS 回调
从应用场景上来看,同步回调跟模板模式几乎一致。它们都是在一个大的算法骨架中,自由替换其中的某个步骤,起到代码复用和扩展的目的。而异步回调跟模板模式有较大差别,更像是观察者模式。
从代码实现上来看,回调和模板模式完全不同。回调基于组合关系来实现,把一个对象传递给另一个对象,是一种对象之间的关系;模板模式基于继承关系来实现,子类重写父类的抽象方法,是一种类之间的关系。
组合优于继承。实际上,这里也不例外。在代码实现上,回调相对于模板模式会更加灵活,主要体现在下面几点。
1.像 Java 这种只支持单继承的语言,基于模板模式编写的子类,已经继承了一个父类,不再具有继承的能力。
2.回调可以使用匿名类来创建回调对象,可以不用事先定义类;而模板模式针对不同的实现都要定义不同的子类。
3.如果某个类中定义了多个模板方法,每个方法都有对应的抽象方法,那即便我们只用到其中的一个模板方法,子类也必须实现所有的抽象方法。而回调就更加灵活,我们只需要往用到的模板方法中注入回调对象即可。