设计模式总结
1.面向对象与结构化编程
(1)结构化编程
即,面向过程式开发。把需要理解成一条一条的业务流程,分析流程,并把这些流程交织组合在一起,划分成一个个功能模块,最后通过一个个函数实现需求。
优点:
把代码分割成多个模块,增强代码的复用性,方便调试、修改。
适用于小型软件,最直接、最简捷的做法。
缺点:
业务流程是需求中最可能变化的地方,而面向过程关注的重点就是业务流程。不能适应变化。
通过划分功能模块、函数间相互调用实现的。需求变化时,就需要更改函数,而牵扯到调用关系、关联的数据,很难弄清楚,难以维护。
(2)面向对象
关注的是对象。对象的优点在于,可定义自己负责的食物,做要求它自己做的事情。对象自己负责自己,而且清楚自己的责任。
把需求理解程一个个对象;弄清楚“这个东西叫什么?从哪里来?能做什么事情”;制造这些对象,让对象相互调用,符合业务需要。
需求变化,通常可以预测哪里会发生变化。可以封装这些变化区域,更容易地将代码与变化产生的影响隔离开来。
对比:
比流程更加稳固、封闭。业务流程从表面上看只有一个入口、一个出口,但每一步都可能改变,对外界产生影响。而对象则是完全通过接口与外界联系,接口内部的事情与外界无关。
面向过程设计开发相对容易,但不容易应对变化。面向对象设计开发困难,却能更好的应对千变万化的世界。
2.抽象、封装、继承、多态
3.单一职责、开放-封闭、依赖倒转、里氏代换、合成聚合复用、迪米特
4.设计模式
面向对象设计模式体现的就是抽象思想。类是对对象的抽象;抽象类是对类的抽象;接口是对行为的抽象。
提高应对变化、复用的设计方案。
有助于提高思考的层次。
(1)创建型模式
隐藏了这些类的实例是如何被创建和放在一起,整个系统关于这些对象所知道的是由抽象类所定义的接口。这样,创建型模式在创建了什么?谁创建了它?它是怎么被创建的?何时创建这些方面提供了很大的灵活性。
使用环境:
当一个系统应该独立于它的产品创建、构成、表示时,可以考虑使用创建性模式。
存在的意义:
抽象化了实例化的过程。帮助一个系统独立于如何创建、组合、表示它的那些对象。
会将关于该系统使用那些具体的类的信息封装起来。
允许客户用结构、功能差别很大的‘产品’对象配置一个系统。配置可以是静态的,即在编译时指定,也可以是动态的,就是运行时再指定。
工厂方法:
只要是在做面向对象开发,创建对象的工作不可避免。
为了避免耦合,多多少少都会用工厂方法来帮助管理创建对象的工作。
使用“对象管理者”工厂来负责特选的对象,可以避免在对象创建时就指明具体的对象,减少耦合,体现了开放-封闭原则、依赖倒转原则、里氏置换原则。
使用:
通常实际是从工厂方法开始,当设计者发现需要更大灵活性时,设计变回向其他创建型模式演化。当设计者在设计标准之间进行权衡的时候,了解多个创建型模式可以给设计者更多的选择余地。
松耦合:
内聚性:描述的是一个例程内部组成部分之间相互联系的紧密程度。
耦合性:描述的是一个例程与其他例程之间联系的紧密程度。
软件开发的目标应该是创建这样的例程:内部完整,即高内聚;而与其他例程之间的联系则是小巧、直接、可见、灵活的,这就是松耦合。
(2)结构型模式
代理与外观的区别:
代理对象代表一个单一对象;而外观对象代表一个子系统。
代理的客户对象无法直接访问目标对象,由代理提供对单独的目标对象的访问;而外观的客户对象可以直接访问子系统中的各个对象,但通常由外观对象提供对子系统各元件功能的简化的共同层次的条用接口。
代理与适配器
都是属于一种衔接性质的功能。代理是一种原来对象的代表,其他需要与这个对象打交道的操作都是和这个代表交涉;适配器不需要虚构出一个代表者,只需要为应付特定使用目的,将原来的类进行一些组合。
桥接与适配器
都是给另一对象提供一定程度的间接性,有利于系统的灵活性。
桥接属于未雨绸缪,在设计之初就想好如何避免问题的发生。
适配器在设计后期使用。
适配与外观
都是对现存系统的封装。
外观定义的是一个新接口,为现存系统提供一个更为方便的访问接口;适配复用原有的接口,是的两个已有的接口协同工作。
适配器是用来适配对象的;外观是用来适配整个子系统的
(3)行为型模式
模板方法之代码重复:
代码重复:是编程中最常见、最糟糕的‘坏味道’。
如果在一个以上的地方看到相同的程序结构,那么可以肯定,设法将它们合二为一,程序会变得更好。
完全相同的代码存在明显的重复;微妙的重复会出现在表面不同但是本质相同的结构、处理步骤中,这种情况需要小心处理。使用继承可以解决此问题。
模板模式由一个抽象类组成,这个抽象类定义了需要覆盖的可能有不同实现的模板方法,每个从这个抽象类派生的具体类将为此模板实现新方法。
这样,所有可重复的代码都提炼到了抽象类中,实现了代码重用。
策略模式之“优先使用对象组合,而非类继承”
继承:提供了一种支持多种算法、行为的方法。可以直接生成类A的子类B、C、D,从而给它不同的行为。
但这样会将行为硬行编制到父类A当中,而将算法的实现与类A的实现混合起来,使得类A难以理解、维护、扩展,也不能动态的改变算法。
仔细分析会发现,B、C、D之间唯一的差别是它们所使用的算法、行为,将算法封装在独立的策略Strategy类中,使得可以独立于基类A改变它,易于切换、理解、扩展。
显然这种情况下,对象组合优于类继承