1.1 设计模式概述
什么是设计模式
设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。
什么是GOF
在 1994 年,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四人合著出版了一本名为 Design Patterns - Elements of Reusable Object-Oriented Software(中文译名:设计模式 - 可复用的面向对象软件元素) 的书,该书首次提到了软件开发中设计模式的概念。
面向接口编程
面向接口编程的真正意思是面向超类型编程,更明确的说,变量的声明类型应该是超类型,通常是一个抽象类或者是一个接口。
优先使用组合而不是继承
使用组合建立系统具有很大的弹性,不仅可以将算法族封装成类,还可以“在运行时动态的改变行为”,只要组合的行为对象符合正确的接口标准。
1.2 UML类图
1.2.1 概念
什么是UML
Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和配置。
UML的好处
可视化功能、说明功能、建造功能、建文档功能
UML九种图
结构型图
行为型图
1.2.2 类图
类图概念
- 类图是显示出类、接口以及它们之间的静态结构和关系的图。
- 类图最基本的元素是类或接口。
- 常见的有以下几种关系:泛化(Generalization)、实现(Realization)、关联(Association)、聚合(Aggregation)、合成(Composition)、依赖(Dependency)。
类图
在上面的类图中可以看出,表示类的框分为以下几层:
- 类名:如果类名是正体字,表明类是具体的,即是可以实例化的,变量名如果是斜体字,表明类是抽象的。
- 属性清单:属性的左面是
+
表示它是public
,-
表示private
,#
表示是protected
。 - 方法清单:方法的左面是
+
表示它是public
,-
表示private
,#
表示是protected
。 - 性质清单:性质是由一个属性,一个赋值函数,一个取值函数构成的。
- 内部成员层:如果一个类有内部成员类,它的类就会有五层,在类的类图中,除了类名层是不能省略,必须显示的以外,其它的几层都可以在UML图中省略。
描述接口的类图
接口的类图和类的类图几乎一样,唯一的区别是接口的名有interface
的字样。
1.2.3 类图中的关系
泛化(Generalization)
是一种继承关系,表示一般与特殊的关系,它指定了子类如何继承父类的所有特征和行为。
实现(Realization)
是一种类与接口的关系,表示类是接口所有特征和行为的实现。
关联(Association)
关联是类与类之间的连接,它使一个类知道另一个类的属性和方法;关联可以是双向的,也可以是单向的。双向的关联可以有两个箭头或者没有箭头,单向的关联有一个箭头。
聚合(Aggregation)
聚合关系是关联关系的一种,是强的关联关系。
聚合是整体与部分的关系,且部分可以离开整体而单独存在。如车和轮胎是整体和部分的关系,轮胎离开车仍然可以存在。
关联和聚合在语法上无法区分,必须考察具体的逻辑关系。
合成(Composition)
合成关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。
合成是整体与部分的关系,但部分不能离开整体而单独存在。
依赖(Dependency)
依赖是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖。
依赖关系在Java中体现为局部变量、方法的参量,以及对静态方法的调用。
1.2.4 时序图
时序图又叫做序列图、活动序列图,作为交互图的一种,时序图按照时间顺序从上往下显示每个使用案例。
时序图的主要用途是把用例表达的需求,转化为进一步、更加正式层次的精细表达。
角色:可以是人或者其他系统、子系统。
生命线:代表一个对象存在的时间。
激活条:对象操作执行时期,处于激活的状态。使用条状矩形表示,附着于对象生命线上 。
消息:消息用从一个对象的生命线到另一个对象生命线的箭头表示。箭头以时间顺序在图中从上到下排列。
同步消息:发送人需要等待消息的响应,实心箭头表示。
异步消息:发送不需等待消息的响应,线性箭头表示。
返回消息:虚线的线性箭头表示。
1.2.5 状态图
状态图(State Diagram)又称做状态转换图(State Transition Diagram)。状态图的基本想法是定义一个具有有限个内部状态的机器,因此状态图又称作有限状态机。对象被外界的时间激发,从而从一个状态转换到另一个状态。
1.3 软件设计原则
1.3.1 开闭原则(Open Close Principle)
- 一个软件实体应当对扩展开放,对修改关闭。
- 在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
- 抽象化:抽象化是开闭原则的关键。
1.3.2 里氏代换原则(Liskov Substitution Principle)
- 任何基类可以出现的地方,子类一定可以出现。
- LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
- 里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
- LSP在设计模式中的体现:策略模式、合成模式、代理模式
1.3.3 依赖倒转原则(Dependence Inversion Principle)
- 要依赖于抽象,不要依赖于具体
- 应当使用Java接口和抽象Java类进行变量的声明、参量的类型声明、方法的返还类型声明、以及数据类型的转换,而非具体Java类。
- 这个原则是开闭原则的基础
- 在设计模式中的体现:工厂方法、模版方法、迭代子模式
1.3.4 接口隔离原则(Interface Segregation Principle)
- 使用多个专门的接口,比使用单个接口要好。
- 它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。
1.3.5 迪米特法则(Demeter Principle)
- 又称为最少知道原则:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
- 做法:优先考虑将一个类设置成不变类、尽量降低一个类的访问权限、谨慎使用Serializable、尽量降低成员的访问权限
- 在设计模式中的体现:门面模式、调停者模式
1.3.6 合成复用原则(Composite Reuse Principle)
尽量使用合成、聚合的方式,而不是使用继承。
1.4 设计模式分类
1.4.1 创建型模式
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用new运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
- 工厂模式(Factory Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 单例模式(Singleton Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
1.4.2 结构型模式
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 过滤器模式(Filter、Criteria Pattern)
- 组合模式(Composite Pattern)
- 装饰器模式(Decorator Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
1.4.3 行为型模式
这些设计模式特别关注对象之间的通信。
- 责任链模式(Chain of Responsibility Pattern)
- 命令模式(Command Pattern)
- 解释器模式(Interpreter Pattern)
- 迭代器模式(Iterator Pattern)
- 中介者模式(Mediator Pattern)
- 备忘录模式(Memento Pattern)
- 观察者模式(Observer Pattern)
- 状态模式(State Pattern)
- 空对象模式(Null Object Pattern)
- 策略模式(Strategy Pattern)
- 模板模式(Template Pattern)
- 访问者模式(Visitor Pattern)
1.4.4 J2EE 模式
这些设计模式特别关注表示层。这些模式是由Sun Java Center鉴定的。
- MVC 模式(MVC Pattern)
- 业务代表模式(Business Delegate Pattern)
- 组合实体模式(Composite Entity Pattern)
- 数据访问对象模式(Data Access Object Pattern)
- 前端控制器模式(Front Controller Pattern)
- 拦截过滤器模式(Intercepting Filter Pattern)
- 服务定位器模式(Service Locator Pattern)
- 传输对象模式(Transfer Object Pattern)