《设计模式:可复用面向对象软件的基础》读书笔记
2021-06-24 15:42:15 32 举报
AI智能生成
南开大学本科课程:《面向对象分析与设计》中,张波老师课上介绍并讲解的18中设计模式,其中含有一个Github的代码仓库,会陆续补充各个模式的实现demo
作者其他创作
大纲/内容
设计模式
实例代码仓库
代码仓库
创造型
抽象工厂-AbstractFactory
意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类
结构
参与者
ConcreteFactory:实现创建具体产品对象的操作
AbstractFactory:声明一个创建抽象产品对象的操作接口
AbstractProduct:为一类产品对象声明一个接口
ConcreteProduct:定义一个将被相应工厂创建的产品对象、实现AbstractProduct接口
Client:仅适用由AbstractFactory和AbstractProduct类声明的接口
效果
分离了具体的类,将客户与类的实现分离
使得易于交换产品系列
有利于产品的一致性
难以支持新种类的产品
生成器-Builder
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
Builder:为创建一个Product对象的各个部件指定抽象接口
ConcreteBuilder
实现Builder的接口以构造和装配该产品的各个部件
定义并明确它所创建的表示
提供一个检索产品的接口
Director:构造一个使用Builder接口的对象
Product
表示被构造的复杂对象
包含定义组成部件的类
使你可以改变一个产品的内部表示
将构造代码和表示代码分开
使你可对构造过程进行更精细的控制
工厂方法-FactoryMethod
定义一个用于创建对象的接口,让子类决定实例化哪一个类。即,使一个类的实例化延迟到其子类
Product:定义工厂方法所创建的对象的接口
ConcreteProduct:实现Product接口
Creator
声明工厂方法,该方法返回一个Product类型的对象。
可以调用工厂方法以创建一个Product对象
ConcreteCreator:重定义工厂方法,以返回一个ConcreteProduct实例
为子类提供挂钩(hook)
连接平行的类层次
原型-Prototype
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
Prototype:声明一个克隆自身的接口
ConcretePrototype:实现一个克隆自身的操作
Client:让一个原型克隆自身从而创建一个新的对象,即上述所提到的框架
运行时刻增加和删除产品
改变值以构造新对象
改变结构以构造新对象
减少子类的构造
用类动态配置应用
单例-Singleton
保证一个类仅有一个实例,并提供一个它的全局访问点
Singleton:
定义一个Instance操作,允许客户访问它的唯一实例
可能负责创建它自己的唯一实例
对唯一实例的受控访问
缩小名空间
允许对操作和表示的精化
允许可变数目的实例
比类操作更灵活
结构型
适配器-Adapter
将一个类的接口转换成客户希望的另一个接口
多重继承适配器
对象组合适配器
Target:定义Client使用的与特定领域相关的接口
Adaptee:定义一个已经存在的接口,这个接口需要适配
Adapter:对Adaptee的接口与Target的接口进行适配
类适配器重定义Adaptee的部分行为更方便
对象适配器允许一次适配多个Adaptee
适配器应该实现所有Adaptee没有实现的必要功能
适配器的工作量取决于目标接口与Adaptee的接口的相似程度
桥接-Bridge
将抽象部分与它的实现部分分离,使他们都可以独立的变化
Abstraction:定义抽象类的接口、维护一个指向Implementor类型对象的指针
RefinedAbstraction:扩充由Abstraction定义的接口
Implementor:定义实现类的接口,该接口不一定要与Abstraction的接口完全一致
ConcreteImplementor:实现Implementor的接口并定义它的具体实现
分离接口以及实现部分
提高可扩充性
实现细节对客户透明
组合-Composite
将对象组合成树形结构以表示 “部分-整体” 的层次结构
使得用户对单个对象和组合对象的使用具有一致性
Component:声明对象接口、实现缺省行为、声明用于访问和管理Component子组件的接口、访问父部件(可选)
Leaf:表示叶节点对象,无子节点、定义对象的行为(实现接口)
Composite:定义有子组件部件的行为、存储子部件、在Component接口中实现与子部件有关的操作
Client:通过Component接口操纵组合部件的对象
可扩展性:添加新组件会很简单
设计更一般化:很难限制组合中的组件,即难以限制某组合中只有A、B、C组件
装饰-Decorator
动态地给一个对象添加一些额外的职责
Component:定义一个对象接口,可以给这些对象动态地添加职责
ConcreteComponent:定义一个对象,可以给这个对象添加一些职责
Decorator:维持一个指向Component对象的指针,并定义一个与Component接口一致的接口
ConcreteDecorator:向组件添加职责
比静态继承更灵活:不会产生很多的新类、很容易重复添加某个特性
避免在层次结构高层的类有太多的特征
Decorator与它的Component不一样,所以装饰时不应该依赖对象标识
每一层包装都是一个对象,所以会需要创建许多额外对象对象
外观-Facade
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
Facade:知道哪些子系统类负责处理请求、将客户的请求代理给适当的子系统对象
Subsystem Classes
实现子系统的功能
处理由Facade对象指派的任务
没有facade的任何相关信息,即不存在指向facade的指针
对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便
实现了子系统与客户之间的松耦合关系
如果应用需要,facade并不限制它们使用子系统
代理-Proxy
为其他对象提供一种代理,以控制对这个对象的访问
Proxy
保存一个引用使得代理可以访问实体
提供一个与Subject接口相同的接口,这样代理就可以替代实体
控制对实体的存取,并可能负责创建和删除它
Subject:定义RealSubject和Proxy的共同接口,这样在能使用RealSubject的地方就能使用Proxy
RealSubject:定义Proxy所代表的实体
代理模式提供了对象间的间接性,而这将会衍生出各方各面的用法,如隐藏等
行为型
职责链-ChainOfResponsibility
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的紧耦合关系
Handler:定义一个处理请求的接口、实现后继链(可做可不做)
ConcreteHandler
处理它所负责的请求
可访问它的后继者
如果可处理请求就处理,不能就转发给后继者
Client:向链上的具体处理者(ConcreteHandler)对象提交请求
降低耦合度
增强了给对象指派职责的灵活性
不保证被接受
命令-Command
将一个请求封装为一个对象,从而用不同的请求对用户参数化
对排队请求或记录请求日志,以及支持可撤销的操作
多组件对应统一操作
实现操作的类和实现接口的类要松耦合
Command:声明执行操作的接口
ConcreteCommand:将一个接收者对象绑定于一个动作、调用接收者相应的操作,以实现Execute
Client:创建一个具体命令对象,并设定它的接收者
Invoker:要求该命令执行这个请求
Receiver:知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者
将调用操作和实现操作的对象解耦
Command对象可以被操纵和扩展
可以将多个命令复合成一个命令
增加新的命令很容易
解释器-Interpreter
给定一个语言,定义它文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子
AbstractExpression(抽象表达式):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享
TerminalExpression(终结符表达式):实现与文法中终结符相关联的解释操作、一个句子中的每个终结符需要该类的一个实例
NonterminalExpression(非终结符表达式)
对文法中每一条规则都需要一个非终结符表达式类
为每个符号都维护一个AbstractExpression类型的实例变量
为文法中的非终结符实现解释(Interpret)操作
Context(上下文):包含解释器之外的一些全局信息
Client:构建相应的抽象语法树、调用解释操作
易于改变和扩展文法
易于实现文法
复杂的文法难以维护
增加了新的解释表达式的方式
迭代器-Iterator
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示
Iterator(迭代器):定义访问和遍历元素的接口
ConcreteIterator(具体迭代器):具体迭代器实现迭代器接口、对该聚合遍历时跟踪当前位置
Aggregate(聚合):定义创建相对应迭代器对象的接口
ConcreteAggregate(具体聚合):实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例
支持以不同的方法遍历一个聚合(先序、中序、后序)
简化了聚合的接口
同一个聚合可以有多个遍历
观察者-Observer
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新
Subject(目标):需要知道它的观察者、提供注册和删除观察者对象的接口
Observer(观察者):为那些在目标发生改变时须获得通知的对象定义一个更新接口
ConcreteSubject(具体目标)
将有关状态存入各ConcreteObserver对象
当它的状态发生改变时,向它的各个观察者发出通知
ConcreteObserver(具体观察者)
维护一个指向ConcreteSubject对象的引用
存储有关状态,这些状态应与目标的状态保持一致
实现Observer的更新接口以使自身状态与目标的状态保持一致
目标和观察者间的抽象耦合
支持广播通信
可能会发生意外的更新
策略-Strategy
定义一些算法,把他们封装起来,并且使它们可以互相替换,使得算法可以独立于使用它的用户而变化
Strategy:定义所有支持算法的公共接口
ConcreateStrategy:实现Strategy接口的具体算法
Context:用一个ConcreateStrategy来配置、维护一个对Strategy对象的引用、可定义一个借口来让Strategy访问它的数据
Context的子类也可以实现不同的算法
较难动态地改变算法
用户必须了解所有Strategy才能选择最合适的算法
访问者-Visitor
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
Visitor(访问者):为该对象结构中的ConcreteElement的每一个类,声明一个Visit操作
ConcreteVisitor(具体访问者):实现每个由Visitor声明的操作。ConcreteVisitor其实是实现了某个具体的功能在不同类之中的实现,例如:类型判断于声明和赋值中如何分别操作的
Element:定义一个Accept操作,它以一个访问者为参数
ConcreteElement(具体元素):实现Accept操作,以操作一个访问者为参数
ObjectStructure(对象结构):能枚举它的元素、可以提供一个高层的接口以允许该访问者访问它的元素、可以是一个复合或是一个集合
访问者模式使得易于增加新的操作
访问者集中相关的操作,而分离无关的操作
增加新的ConcreteElement类很困难
通过类层次进行访问:迭代器只能访问有共同父类的Item,然而访问者没有这个限制
破坏封装:访问者方法假定ConcreteElement接口的功能足够强,足以让访问者进行他们的工作,但是往往这样的条件无法达成,迫使提供元素内部状态的公共操作,这可能会破坏它的封装性
0 条评论
下一页