代码重构总结
框架都是遵循依赖倒置(DIP)原则的一类软件,并且还会满足"不要来调用框架,框架会来调用你” 的好莱坞原则。使用一个框架是要遵循框架的约定来进行编程,框架会按照约定去调用你的实现。所有的框架其实都是一种策略模式,同时策略模式也是符合DIP规则的。
一、JUnit中的设计模式
1.策略模式
在策略模式里面一定有一个应该程序,一个策略接口儿,再有一个策略实现。
在上图中有两个策略模式:
Edlipse跑TestCase这是一个策略模式
Eclipse定义了一套plug-in的接口规范,然后JUnit实现了这套接口,所以Eclipse可以作为一个高层框架来调用junit,这正好符合了依赖倒置原则和好莱坞原则,
然后Eclipse就可以加载jUnit作为自己的一个插件,加载这个插件之后在菜单里可以显示。我们的Test能在Ecplise里运行,是因为Ecplise里有一个策略模式。应用程序就是Ecplise这个IDE本身,策略的接口就是Ecplise的plug-in,而策略的实现是jUnit实现了这些接口,所以jUint才能在Ecplise里运行。
我们经常说的做软件架构要做插件化的软件架构,其实这种架构就是策略模式的一种应用而已。
整个依赖倒置原则其实就是一个策略模式。
定义一个接口或是抽象类,应用程序是按照抽象类进行编程的,然后由多个不同的实现来完成的。而运行的时候是运行其中的一个实现。这种都叫做策略模式。
Edlipse跑TestCase超类的具体实现类
XyzTests是实现了TestCase策略接口(准确的说它应该是一个策略的抽象类)的具体策略,它和抽象类接口是一样的。
我们基于TestCase可以写N个策略实现类,具体的策略实现就是xyztest,Eclipse其实就是应用程序
什么时候使用策略模式?
系统需要在多种算法中选择一种,例如系统重构的场景,将条件语句转换成对于策略的多态性调用
优点: 策略模式将使用策略的人和策略的具体实现分离,策略对象可以自由组合
缺点:策略模式仅仅封装了“算法的具体实现”,方便添加和替换算法。但它并不关心何时使用何种算法,这个必须由客户端来决定
2.模版方法模式
定义:在基类里定义一个模版,然后在子类里面去实现模版里面具体的方法。
模版的流程在基类里面去定义,模版的实现在子类里去完成。
特点:1.模版方法模式是扩展功能的最基本模式之一,它是一种”类的行为模式”
2.它是通过“继承”的方法来实现扩展,基类负责算法的轮廓和骨架,子类负责算法的具体实现。
3.基于“继承“的模版方法比”组合”更容易实现,同时
形式:
抽象方法:protected abstract void step1(),强制子类实现该步骤
具体方法:protected void doSomething() {…},子类不需要覆盖,但也可以覆盖之。
如果想要明确告诉子类“不要覆盖它”,最好标明:final
钩子方法:protected void setUp(){ }
空的实现(确性适配器模式)
子类课选择性的覆盖之,以便在特定的时机做某些事
上图中runBare就是模版方法,它定义了模版和具体方法的执行顺序。
3.组合模式
组合(Composite)模式是一种对象的行为模式。
将对象组合成树形结构以表示“部分-整体”的层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性。
组合模式的本质:统一叶子对象和组合对象。
组合模式的目的:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统一的方式来操作。
角色和职责
抽象组件(Component)角色:为组合对象和叶子对象声明公共的接口,让客户端可以通过这个接口
来访问和管理整个对象树,并可以为这些定义的接口提供缺省的实现。
组合对象(Composite)角色:通常会存储子组件(组合对象、叶子对象),定义包含子组件的那些组件
的行为,并实现在抽象组件中定义的与子组件有关的操作,例如子组件
的添加(addChild)和删除(removeChild)等。
叶子对象(Leaf)角色:定义和实现叶子对象的行为,并且它不再包含其他的子节点对象。
客户端(Client)角色:通过Component接口来统一操作组合对象和叶子对象,以创建出整个对象树结构。
4.装饰模式
定义
它是一种“对象的结构模式”,也被笼统地称为“包装器”。适配器也别称作“包装器”,区别在于适配器是转换成另一个接口,而装饰器是保持接口不边。
作用
在不改变对客户端的接口的前提下,扩展现有对象的功能。
例子
包装器形成了一条链
特点
1.装饰器和模版方法、策略模式的比较
1.1 装饰器保持对象的功能不变,扩展其外网的功能
1.2 模版方法和策略模式则保持算法的框架不变,而扩展其内部的实现
2.装饰器和继承的比较
2.1 他们都可以用来扩展对象的功能
2.2 但装饰器是动态的,继承是静态的
2.3 装饰器是可以任意组合的,但这也使装饰器更加复杂,有可能会组合出荒谬的结果
评论