设计模式(Dessert)
面向对象编程的 3 个要素
封装:隐藏实现, 定义接口。
继承:IS-A 关系,HAS-A 关系(组合)。
多态: 后期绑定,向上转型(up casting)。
面向对象编程(利用多态的性质)
充血模型,贫血模型,领域驱动设计。
面向对象设计的目标
强内聚,低耦合。
软件中的臭味如:僵硬, 脆弱,不可移植,导致误用的陷阱,晦涩,过渡设计,copy-paste 代码。
OCP 开闭原则(OOD 原则)
对扩展开放, 对更改关闭。
使用方法如:抽象,策略模式, 适配器模式,观察者模式。
DIP 依赖倒置原则
高层不依赖低层模块,而大家都依赖抽象。抽象不能依赖实现,而是实现依赖抽象。
框架的核心 - 好莱坞规则 (Don’t call me ,I call you)
Liskov 里氏替换原则
一个正确的基础符合什么要求?
若对每个类型 T1 的对象 o1,都存在一个类型 T2 的对象 o2,使得在所有针对T2 编写的程序 P 中,用 o1 替换 o2 后,程序 p 的行为功能不变,则 T1 是 T2 的子类型。子类型必须能够替换掉它们的基类型。
不符合 IS-A 的关系的继承,一定不符合 LSP。 IS-A 关系是关于行为的,
从“契约”的角度来看凡事使用基类的地方,一定也适用于其子类。
SRP 单一职责原则
一个模块组成元素之间的功能相关性,一个类只能有一个引起它变换的原因。
ISP 接口分离原则
不应该强迫客户端程序依赖他们不需要的方法。ISP 和 SRP 是相关的 都和 “内聚有关”,SRP 指出如何设计一个类 (只能有一个原因才能是类发生改变), ISP 指出应该如何设计一个接口(从客户端的需要出发,强调不让客户看到他们不需要的方法)。
设计模式分类
功能划分
创建型:
简单工程模式:简单工程非常重要,是许多其它模式的基础。类图如下:
引用课程中的例子加深一下印象(如图)
优点:对与 Client 和 Factory 满足 OCP 。实现的方式为抽象+动态编程(将编译时的类型检查转变为运行时的检查)
缺点:缺少编译时类型安全。限制类 Sort 只能通过默认构造函数创建。
Singleton 单例模式:保证产生单一实例,一个类只生产一个实例。类图如下:
优点:可减少实例频繁创建和销毁带来的资源消耗,当多个用户使用实例的时候,以便于进行统一控制。
关键点:声明私有构造方法,单例中的成员变量是多线程重用的,因此尽量将单例设计成无状态服务(只提供服务,不保存状态)。
结构型:
适配器模式:系统需要使用现有的类,而这个类的接口于我们所需要的不同。类图如下:
组合模式:是一种对象的机构模式。
装饰器模式:是一种对象的机构模式。可以在不改变对客户端的结构前提下,扩展对象的功能。类图如下:
类常以包装器(wrapper)方式使用。适配器也被称作包装器,区别在于适配器转换成另外一个接口,而装饰器保持接口不变,包装器形成一条 “链”。对比模版方法,策略模式装饰器保持对象功能不变,扩展其外围功能。模版方法和策略模式则保持算法框架不变,而扩展其内部实现。对比继承都可以用来扩展功能,装饰器是动态的,继承是静态的。装饰器可以任意组合(但这也使装饰器更复杂)。
行为型:
模版方法模式:通过继承的方法来实现扩展,基类负责算法的轮廓和骨架,子类负责算法的具体实现。类图如下:
可以实现的方式有:1.抽象方法(声明抽象方法,强制子类实现该步骤)。2.具体方法(子类不需要覆盖,但也可以覆盖)。3.钩子方法(空实现,子类可以选择型的覆盖,以便于特定的时机做事)。
策略模式:同过组合的方式来实现扩展。重构系统时可将条件语句转换为对于策略的多态性调用。类图如下:
对比模版方法可将使用策略的人与策略的实现实现分类,策略对象可以随意组合。存在问题就是:策略模式仅仅封装了算法的具体实现,方便添加和替换算法,同不关心何时使用这种算法。这个必须有客户端来决定。
从方式分
类模式
以继承的方式实现模式-静态
对象模式
已组合的方式实现-动态
总结
每一种模式都是描述了一种问题的通用解决方案,设计模式是一种可重复使用的解决方案。
设计模式包含 4 个部分:1.模式的名称(有助于表达我们的设计)。2.代解决的问题(描述了何时需要运用这种模式)。3.解决方案(组成设计的元素(类和对象),它们之间的关系,职责以及合作)。4.结论(运用这种解决方案带来的利弊【主要使是对系统的弹性,扩展性和可移植性的影响】。
附录
装饰模式的应用案例:
Jave Servlet
HttpServletRequest/HttpServletRequestWrapper
HttpServletResponse/HttpServletResponseWrapper
同步化装饰器
Collections.synchronizeList
Java I/O 类库
核心:流,即数据有序排列,将数据从源送达到目的地
流的种类:InputStream, OutputStream - byte 流(8 位字节流)。Reader,Writer - 代表 char 流(Unicode 字符流)。
流的对称性:输入 - 输出,Byte - Char
版权声明: 本文为 InfoQ 作者【Arvin】的原创文章。
原文链接:【http://xie.infoq.cn/article/2e4edc427b63f3b140ab90ca8】。文章转载请联系作者。
评论