SlideShare una empresa de Scribd logo
1 de 216
Agenda
概述
- 简要介绍模式的概念、地位、构成、分类以及描述方法。
设计原则
- 设计原则是设计目标的高度抽象,模式是实现这些原则的具体方法。
设计模式
- 主要介绍了GOF23种软件设计模式。
架构模式
- 主要介绍了架构设计的几种模式。
练习
参考资料
- 培训只能入门,需要在日常工作中积累提高,请保持阅读习惯。
概 述
模式是什么
模式是指从生产经验和生活经验中经过抽象和升华
提炼出来的核心知识体系。模式其实就是解决某一类问
题的方法论。把解决某类问题的方法总结归纳到理论高
度,那就是模式。模式是一种指导,在一个良好的指导
下,有助于你完成任务,有助于你作出一个优良的设计
方案,达到事半功倍的效果。而且,会得到解决问题的
最佳办法。
模式在知识理念中的地位
抽象的(abstract)
具体的(concrete)
模式的构成
 Context(语境)
设计问题产生的上下文背景
 Problem(问题)
给定语境中重复出现的问题
-- 解决方案必须满足的需求
-- 你必须考虑的约束
-- 解决方案必须具有期望的特性
 Solution(解决方案)
针对该问题,证实有效的解决方案
-- 规定了一个特定的结构
-- 规定了运行期间的行为
模式的作用
 一个模式关注一个在特定设计环境中出现的重复设计问题
 各种模式用文档方式记录现有的、经充分考验的设计经验
 模式明确并指明处于单个类和实例层次或组件层次之上的抽象
 模式为设计原则提供一种公共的词汇和理解
 模式是为软件体系结构建立文档的一种手段
 模式支持用已定义的属性来构造软件
 模式有助于建立一个复杂的和异构的软件体系结构
 模式有助于管理软件复杂度
一个软件体系结构的模式描述了一个出现在特定设
计语境中的特殊的再现设计问题,并为它的解决方案提
供了一个经过充分验证的通用图式。解决方案图式通过
描述其组成组件、它们的责任和相互关系以及它们的协
作方式来具体指定。
模式的层次分类
架构模式
(Architecture
Styles)
-- 是系统的高层次策略 ,涉及到大尺度的组件以及整体性质
-- 可作为具体软件体系结构的模板,是开发一个软件系统时的基本设计决策
--规定了系统范围结构特性,架构模式的好坏影响到总体布局和框架性结构
设计模式
(Design Patterns)
--是中等尺度的结构策略。实现了一些大尺度组件的行为和它们之间的关系
--模式的好坏不会影响到系统的总体布局和总体框架
--设计模式定义出子系统或组件的微观结构
代码模式
(Idioms)
--是特定的范例和与特定语言有关的编程技巧
--处理特定设计问题的实现,关注设计和实现方面
--模式的好坏会影响中等尺度组件的内部、外部的结构或行为的底层细节
模式描述
 名称:模式的名称和一个简短的摘要
 别名:模式的其他名称,如果知道的话
 例子:用来说明问题存在和需要模式的一个真实世界的例子
 语境:模式可以应用的情形
 问题:模式解决的问题,包括其相关强制条件的讨论
 解决方案:以该模式为基础的基本解决方案原理
 结构:模式结构方面的详细的规格说明
 动态特性:描述模式运行期间行为的典型场景
 实现:实现模式的指南
 已解决的例子:针对解决没有包括在上述小节中例子的一些重要方面讨论
 变体:模式变体或特例的简短描述
 已知使用:从已存在的系统中给出模式使用的例子
 效果:模式提供的优点和模式存在的潜在不足
 参见:参考那些解决相似问题的模式,并且参考其他一些模式,有助细化
设计原则
参考:《Design Principles and Design Patterns》, Robert C. Martin
http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf
面向对象设计原则(1) - SOLID
 *开放封闭原则(OCP, Open Closed Principle)
 模块应该对扩展开放,对更改封闭
 依赖倒置原则(DIP, Dependency Inversion Principle)
 依赖抽象,不要依赖实现;高层模块(稳定)不应该依赖于底层模块(变化),二
者都应该依赖于抽象;抽象(稳定)不应该依赖于实现细节(变化),实现细节应
该依赖于抽象
 单一职责原则(SRP, Single Responsibility Principle)
 一个类应该仅有一个引起它变化的原因,应该只有一个职责;每一个职责都是变化
的一个轴线,如果一个类有多个职责,这些职责就耦合在了一起
 Liskov替换原则(LSP, Liskov Substitution Principle)
 子类必须能够替换它们的基类(IS-A);如果调用的是父类的话,那么换成子类也
完全可以运行
 接口隔离原则(ISP, Interface Segregation Principle)
 每一个接口应该是一种角色;多个客户特定的接口强于一个通用目的的接口,不应
该强迫客户程序依赖它们不用的方法
面向对象设计原则(2)
 *最少知识原则(迪米特法则)
 一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。一个软件实体应当
尽可能少的与其他实体发生相互作用;每一个软件单位对其他的单位都只有最少的
知识,而且局限于那些与本单位密切相关的软件单位。
 针对接口编程,而不是针对实现编程
 客户无需知道所使用对象的特定类型,只需要知道对象拥有客户所期望的接口
 优先使用对象组合,而不是类继承
 类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。继承在某种程度上破
坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对象具有良好定义
的接口,耦合度低。
 封装变化点
 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不
会对另一侧产生不良的影响,从而实现层次间的松耦合。
面向对象设计原则(3:包结构原则)
 The Release Reuse Equivalency Principle(REP)
 The granule of reuse is the granule of release(软件包的粒度与可重用的粒度保
持一致)
 The Common Closure Principle(CCP)
 Classes that change together, belong together(一致变化的类,应该属于同
一个包)
 The Common Reuse Principle(CRP)
 Classes that aren’t reused together should not be grouped together(不被
一起重用的类,不放到一个包里)
高内聚(Cohesion)
面向对象设计原则(4:包结构原则)
 The Acyclic Dependencies Principle(ADP)
 The dependencies between packages must not form cycles(软件
包之间不能相互依赖,构成依赖循环)
 The Stable Dependencies Principle(SDP)
 Depend in the direction of stability(包之间的依赖关系都应该是稳定方
向依赖的,包要依赖的包要比自己更具稳定性)
 The Stable Abstractions Principle(SAP)
 Stable packages should be abstract packages(稳定的包,应该是
抽象的包,以此带来可变性)
低耦合(Coupling)
设计模式
(Design Patterns)
设计模式
 起源
《Design Patterns: Elements of Reusable Object-Oriented Software》,GOF23
种设计模式。
 发展
增加了一些类别,最重要的是使涵盖范围扩展到更具体的问题类型。例如:
-《Patterns in Java》增加了解决涉及诸如并发等问题的模式,
-《Core J2EE Patterns》主要关注使用Java2企业技术的多层应用程序上
的模式。
GOF-23设计模式分类
从目的来看
 创建型模式(Creational): 将对象的部分创建工作延迟到子类或者其他
对象,从而应对需求变化为对象创建时具体类型实现引来的冲击。
 结构型模式(Structural):通过类继承或者对象组合获得更灵活的结构,
从而应对需求变化为对象的结构带来的冲击。
 行为型模式(Behavioral):通过类继承或者对象组合来划分类与对象间
的职责,从而应对需求变化为多个交互的对象带来的冲击。
从范围来看
 类模式处理类与子类的静态关系
 对象模式处理对象间的动态关系
GOF-23设计模式概览
创建型 结构型 行为型
类
Factory Method Adapter_Class Interpreter
Template Method
对象
Abstract Factory
Builder
Prototype
Singleton
Adapter_Object
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Chain of Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
从封装变化角度对模式分类
 对象创建
 Factory Method
 Abstract Factory
 Prototype
 Builder
 组件协作
 Template Method
 Observer / Event
 Strategy
 单一职责
 Decorator
 Bridge
 对象性能
 Singleton
 Flyweight
 接口隔离
 Facade
 Proxy
 Mediator
 Adaptor
 状态变化
 Memento
 State
 数据结构
 Composite
 Iterator
 Chain of
Responsibility
 行为变化
 Command
 Visitor
 领域问题
 Interpreter
来源:祝成科技软件开发培训
www.softcompass.com
“对象创建”模式
通过“对象创建”模式对象绕开new,来避免对象创建(new)过
程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。
它是接口抽象之后的第一步工作。
典型模式
 Factory Method
 Abstract Factory
 Prototype
 Builder
Factory Method模式
举例
你是一个ATM机软件的开发工程师,需要测试ATM软件的存取款功能,但在测试时
不想产生实际的银行业务,该怎么办呢?
public class ATMGui{
……
private Status doWithdrawal(Account account, float amount) {
Transaction transaction = new Transaction();
transaction.setSourceAccount(account);
transaction.setDestAccount(myCashAccount());
transaction.setAmount(amount);
transaction.process();
if (transaction.successful()) {
dispense(amount);
}
return transaction.getStatus();
}
}
Public class ATMGuiTest{
… …
public void testCheckingWithdrawal() {
float startingBalance = balanceForTestCheckingAccount();
AtmGui atm = new AtmGui();
insertCardAndInputPin(atm);
atm.pressButton("Withdraw");
atm.pressButton("Checking");
atm.pressButtons("1", "0", "0", "0", "0");
assertContains("$100.00", atm.getDisplayContents());
atm.pressButton("Continue");
assertEquals(startingBalance - 100,
balanceForTestCheckingAccount());
}
}
Factory Method模式
class Class Model
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Version EA 9.0 Unregistered Trial Versio
ATMGui
+ doWithdrawal() :void
+ createTransaction() :void
MockedATMGui
+ createTransaction() :void
ConcreteATMGui
+ createTransaction() :void
ATMGuiTest
+ testCheckingWithdrawal() :void Transaction transaction =
createTransactioin();
......
return new MockedTransaction(); return new RealTransactioin();
ATMGui gui = new MockedATMGui();
......
Factory Method模式
动机
 在软件系统中,经常面临着创建对象的工作;由于需求的变化,需
要创建的对象的具体类型经常变化。
 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一
种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧
耦合?
意图
 定义一个用于创建对象的接口,让子类决定实例化哪一个类。
Factory Method使得一个类的实例化延迟到子类
Factory Method模式
结构
适用性
 当一个类不知道它所必须创建的对象的类的时候
 当一个类希望由它的子类来指定它所创建的对象的时候
 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希
望将哪一个帮助子类是代理者这一信息局部化的时候。
 解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同
Template
Method,
具有实际
的逻辑和
意义
该类型对客户
端是否隐藏呢?
Abstract Factory模式
举例
Java可以根据变成人员的要求改变界面风格,如Windows风格,Java风格等,
这是怎么做到的呢?
Abstract Factory模式
Abstract Factory模式
动机
 在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;
同时,由于需求的变化,往往存在更多系列对象的创建工作。
 如何应对这种变化?如何绕过常规的对象创建方法(new),提供一
种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”
的紧耦合?
意图
 提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对
象”,无需指定它们具体的类。
Abstract Factory模式
结构
适用性
 一个系统要独立于它的产品的创建、组合和表示时。
 一个系统要由多个产品系列中的一个来配置时。
 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
 当你提供一个产品类库,而只想显示它们的接口而不是实现时。
 主要用于应对“新系列”的需求变动。缺点在于难以应对“新对象”
的需求变动
Prototype模式
举例
细胞通常具有非常复杂的结构。在生物工程模拟细胞分裂时,如何
快速实现从一个细胞到两个细胞的创建工作?
Prototype模式
动机
 在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;
由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥
有比较稳定一致的接口。
 如何应对这种变化?如何向“客户程序(使用这些对象的程序)”
隔离出“这些易变对象”,从而使得“依赖这些易变对象的客户程
序”不随着需求改变而改变?
意图
 使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建
新的对象。
Prototype模式
结构
适用性
 当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者
 为了避免创建一个与产品类层次平行的工厂类层次时;或者
 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数
目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方
便一些。
Builder模式
举例
ProtocolBuffer中,要实现协议类的快速序列化与反序列化,在协议类的实现中封
装了非常复杂的数据结构,而ProtocolBuffer的使用者,不希望用很复杂的方法来创建
该协议类。
message Request {
// RPC service full name
required string service_name = 1;
// RPC method name
required string method_name = 2;
// RPC request proto
required bytes request_proto = 3;
}
Request.Builder builder = Request.newBuilder();
builder.setServiceName(…);
builder.setMethodName(…);
builder.setRequestProto(…);
Request request = builder.build();
Builder模式
场景
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通
常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复
杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的
算法却相对稳定。
Builder模式
动机
 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通
常由各个部分的子对象用一定的算法构成;由于需求的变化,这个
复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一
起的算法却相对稳定。
 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对
象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随
着需求改变而改变?
意图
 将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以
创建不同的表示。
Builder模式
结构
适用性
 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装
配方式时。
 当构造过程必须允许被构造的对象有不同的表示时。
 (变化点在哪里,封装在哪里)主要在于 “分步骤构建一个复杂的
对象” 。其中“分步骤”是一个稳定的算法,复杂对象的各个部分
则经常变化。缺点在于难以应对“分步骤构建算法”的需求变动。
“组件协作”模式
现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,
“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松
耦合,是二者之间协作时常用的模式。
典型模式
 Template Method
 Observer / Event
 Strategy
Template Method模式
举例
对于写Servlet的开发人员,常常只需要指定如何处理Get、Post、Put等几个少数的方
法就可以了,而对于一些复杂的处理过程,如把字节流转换为ServletRequest对象,
或从字节流中识别不同请求类型并分发到合适的处理方法,可以一概都不需要知道。
public abstract class HttpServlet extends GenericServlet implements java.io.Serializable {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//略 …
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod(); // 取得請求的方法
if (method.equals(METHOD_GET)) { // HTTP GET
// 略...
doGet(req, resp);
// 略 ...
} else if (method.equals(METHOD_HEAD)) { // HTTP HEAD
// 略 ...
doHead(req, resp);
} else if (method.equals(METHOD_POST)) { // HTTP POST
// 略 ...
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) { // HTTP PUT
// 略 ...
}
}
Template Method模式
动机
 在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结
构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比
如框架与应用之间的关系)而无法和任务的整体结构同时实现。
 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化
或者晚期实现需求?
意图
 定义一个操作中的算法的骨架(稳定),而将一些步骤(变化)延迟到
子类中。Template Method使得子类可以不改变一个算法的结构
即可重定义(override 重写)该算法的某些特定步骤。
Template Method模式
结构
适用性
 一次性实现一个算法的不变的部分,将可变的行为留给子类来实现。
 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免
代码重复。是“重分解以一般化”的一个很好的例子。
 控制子类扩展。模板方法只在特定点调用“hook”操作(参见效
果一节),这样就只允许在这些点进行扩展。
 被Template Method调用的虚方法一般推荐设置为protected。
Observer / Event模式
举例
Java NIO非堵塞技术是如何实现的?以下是采用Netty创建服务端的代码片段。
public class HelloServer {
public static void main(String args[]) {
// Server服务启动器
ServerBootstrap bootstrap = new ServerBootstrap(…);
// 设置一个处理客户端消息和各种消息事件的类(Handler)
bootstrap .setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline() throws Exception {
return Channels .pipeline(new HelloServerHandler());
}
});
// 开放8000端口供客户端访问。
bootstrap.bind(new InetSocketAddress(8000));
}
private static class HelloServerHandler extends
SimpleChannelHandler {
// 当有客户端绑定到服务端的时候触发,打印"Hello world, I'm server."
@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
System.out.println("Hello world, I'm server.");
}
}
}
Observer / Event模式
动机
 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关
系”,即一个对象(目标对象)的状态发生改变,所有的依赖对象
(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,将
使软件不能很好地抵御变化。
 使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的
依赖关系。从而实现软件体系结构的松耦合。
意图
 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生
改变时,所有依赖于它的对象都得到通知并自动更新
Observer / Event模式
结构
适用性
 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这
二者封装在独立的对象中以使它们可以各自独立地改变和复用。
 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少
对象有待改变。
 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换
言之, 你不希望这些对象是紧密耦合的。
Strategy模式
举例
负载均衡是分布式计算中常见的问题,实现负载均衡有很多不同算法,如随机算法、
RoundRobin算法、一致性Hash算法等。(1) 运维人员可能根据需要随时调整负载均衡
策略;(2) 将来可能有更新更好的负载均衡算法。我们应该如何设计我们的分布式框架?
Protected Node getNode(LoadBalanceType type) {
if (RANDOM == type) {
return getRandomNode();
} else if (ROUNDROBIN == type) {
return getRoundRobinNode();
} else if …
}
Strategy模式
动机
 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,
如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且
有时候支持不使用的算法也是一个性能负担。
 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身
解耦,从而避免上述问题?
意图
 定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。
该模式使得算法可独立于使用它的客户而变化。
Strategy模式
结构
适用性
 “策略”及其子类为组件提供了一系列可重用的算法,从而可以使
得类型在运行时方便地根据需要在各个算法间进行切换。
 提供了用条件判断语句以外的另一种选择,消除条件判断语句,就
是在解耦合。
 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂
的、与算法相关的数据结构。
“单一职责”模式
在软件组件的设计中”,如果责任划分的不清晰,使用继承得到的
结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,
这时候的关键是划清责任。
典型模式
 Decorator
 Bridge
Decorator模式
举例
SiteMesh是由一个基于Web页面布局、装饰以及与现存
Web应用整合的框架。它能帮助我们在由大量页面构成
的项目中创建一致的页面布局和外观,如一致的导航条,
一致的banner,一致的版权,等等。 它不仅仅能处理
动态的内容,如jsp,php,asp等产生的内容,它也能
处理静态的内容,如htm的内容,使得它的内容也符合
你的页面结构的要求。甚至于它能将HTML文件象
include那样将该文件作为一个面板的形式嵌入到别的文
件中去。所有的这些,都是GOF的Decorator模式的最生
动的实现。尽管它是由java语言来实现的,但它能与其
他Web应用很好地集成。
Decorator模式
动机
 在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,
由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;
并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展
功能的组合)会导致更多子类的膨胀(多继承)。
 如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免
“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩
展变化”所导致的影响将为最低?
意图
 动态地给一个对象增加一些额外的职责。就增加功能而言,
Decorator模式比生成子类更为灵活。
Decorator模式
结构
适用性
 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
 处理那些可以撤消的职责。
 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立
的扩展,为支持每一种组合将产生大量的子类,子类数目呈爆炸性增长。
另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
 并非解决“多子类衍生的多继承”问题,应用的要点在于解决“主体类
在多个方向上的扩展能力”——是为“装饰”的含义
Bridge模式
举例
手机品牌和软件是两个概念,不同的软件可以在不同的手机上,不同的手机可以有相同
的软件,两者都具有很大的变动性。如果我们单独以手机品牌或手机软件为基类来进行
继承扩展的话,无疑会使类的数目剧增并且耦合性很高。这时候我们应该怎么办?(如
果更改品牌或增加软件都会增加很多的变动)两种方式的结构如下:
手机这个例子可能很直观,想想关于状态的例子?当我们需要各种不同状态的复杂组
合时,考虑一下Bridge模式吧。
Bridge模式
Bridge模式
动机
 由于某些类型的固有逻辑,使得它们具有两个变化的维度,乃至多
个纬度的变化。
 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类
型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
意图
 将抽象部分与实现部分分离,使它们都可以独立地变化。
Bridge模式
结构
适用性
 使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使
得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬
度的变化,即“子类化”它们。
 有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即
一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承
方案更好的解决方法。
 应用一般在“两个非常强的变化强度”
“对象性能”模式
面向对象很好地解决了“抽象”的问题,但是必不可免地要付出一
定的代价。对于通常情况来讲,面向对象的成本大都可以忽略不计。
但是某些情况,面向对象所带来的成本必须谨慎处理。
典型模式
 Singleton
 Flyweight
Singleton模式
举例
每一个Java程序实际上都是启动了一个JVM进程。我们如何在Java程序中获取当前
JVM的状态呢?
 Runtime类封装了运行时的环境。每个 Java 应用程序都有一个 Runtime 类实例,
使应用程序能够与其运行的环境相连接。
 一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,
但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用。
 一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控
制Java虚拟机的状态和行为。
Runtime run = Runtime.getRuntime();
System.out.println(“JVM最大内存:” + run.maxMemory());
System.out.println(“JVM空闲内存:” + run.freeMemory());
Singleton模式
动机
 在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中
只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?
这应该是类设计者的责任,而不是使用者的责任。
意图
 保证一个类仅有一个实例,并提供一个该实例的全局访问点。
Singleton模式
结构
适用性
 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改
代码就能使用一个扩展的实例时。
 实例构造器可以设置为protected以允许子类派生;一般不要支持序
列化和ICloneable接口,因为有可能导致多个对象实例。
 不能应对多线程环境:在多线程环境下,仍然有可能得到多个实例对
象(需要加信号量)
Flyweight模式
举例
字符串在大多数应用程序中的出现频率较高,Java必须对字符串的执行进行优化
以保证效率。执行以下代码,看看结果和你预期的是否一致?
public class StringTest {
public static void main(String[] args) {
String fly = "fly", weight = "weight";
String fly2 = "fly", weight2 = "weight";
System.out.println(fly == fly2); // ?
System.out.println(weight == weight2); // ?
String distinctString = fly + weight;
System.out.println(distinctString == "flyweight"); // ?
String flyweight = (fly + weight).intern();
System.out.println(flyweight == "flyweight"); // ?
}
}
Flyweight的另一个典型例子是Java Swing。请查阅相关资料,指出Swing树的速
度是如何做到这么快的。(秘密在TreeCellRenderer.getTreeCellRendererComponent()里)
Flyweight模式
动机
 采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统
中,从而带来很高的运行时代价——主要指内存需求方面的代价。
 如何在避免大量细粒度对象问题的同时,让外部客户程序仍然能够
透明地使用面向对象的方式来进行操作?
意图
 运用共享技术有效地支持大量细粒度的对象。
Flyweight模式
结构
适用性
 主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
 采用对象共享的做法降低系统中对象的个数,从而降低细粒度对象给
系统带来的内存压力。具体实现时,要注意对象状态的处理。对象的
大多数状态都可变为外部状态,如果删除对象的外部状态,那么可以
用相对较少的共享对象取代很多组对象。
 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?
需要根据具体应用情况进行评估,而不能凭空臆断。
“接口隔离”模式
在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题、
甚至根本无法实现。采用添加一层间接接口,来隔离本来互相紧密
关联的接口是一种常见的解决方案。
典型模式
 Facade
 Proxy
 Mediator
 Adaptor
Facade模式
举例
汽车启动时,电瓶中的电能转化成起动机机械能,从而由曲轴带动发动机转动,同时点火、
喷油在缸内燃烧,作工。发动机是一种能量转换机构,它将燃料燃烧产生的热能转变成机
械能,发动机的一个工作循环包括四个过程:进气、压缩、作功、排气。发动机有很多种,
如四行程汽油机、二行程汽油机等,工作机制又各有不同,…
其实说了这么多,开车司机点火的时候所要做的就是,把点火钥匙插入钥匙孔,轻轻一转
就可以了。
Facade模式
动机
 上述A方案的问题在于组件的客户和组件中各种复杂的子系统有了
过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦
合面临很多变化的挑战。
 如何简化外部客户程序和系统间的交互接口?如何将外部客户程序
的演化和内部子系统的变化之间的依赖相互解耦?
意图
 为子系统中的一组接口提供一个一致的界面,Façade模式定义了
一个高层接口,这个接口使得这一子系统更加容易使用。
A方案 B方案
Facade模式
结构
适用性
 简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,
从某种程度上也达到了一种“解耦”的效果——内部子系统的任何变
化不会影响到Façade接口的变化。
 更注重从架构的层次去看整个系统,而不是单个类的层次
 并非一个集装箱,可以任意地放进任何多个对象。Façade模式中组
件的内部应该是“相互耦合关系比较大的一系列组件”,而不是一个
简单的功能集合。
Proxy模式
举例
(1)远程代理(Remote Proxy)
(2)虚代理(Virtual Proxy)
(3)保护代理(Protection Proxy)
(4)智能指针(Smart Reference)
Proxy模式
动机
 在面向对象系统中,有些对象由于某种原因(比如对象创建的开销
很大,或者某些操作需要安全控制,或者需要进程外的访问等),
直接访问会给使用者、或者系统结构带来很多麻烦。
 如何在不失去透明操作对象的同时来管理/控制这些对象特有的复
杂性?增加一层间接层是软件开发中常见的解决方式。
意图
 为其他对象提供一种代理以控制对这个对象的访问。
Proxy模式
结构
适用性
 在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy
模式。
 具体实现方法、实现粒度都相差很大。可能针对单个对象也可能针对组
件模块做proxy
 并不一定要求保持接口的一致性,只要能够实现间接控制,有时候损失
一些透明性是可以接受的
Mediator模式
举例
试想繁忙的首都国际机场,每天进出港航班达上千次,如果没有机场飞行控制系统(就
是传说中的塔台)是难以想象的。塔台具有绝对的权利,他可以控制任何一架飞机的起
飞和降落时间以及地方,而飞机和飞机之间不允许通信。
同事关系
中介者
Mediator模式
动机
 在软件构建过程中,经常会出现多个对象互相关联交互的情况,对
象之间常常会维持一种复杂的引用关系,如果遇到一些需求的更改,
这种直接的引用关系将面临不断的变化。
 在这种情况下,我们可使用一个“中介对象”来管理对象间的关联
关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵
御变化。
意图
 用一个中介对象来封装一系列的对象交互。中介者使各对象不需要
显式的相互引用,从而使其耦合松散,而且可以独立地改变它们之
间的交互。
Mediator模式
结构
适用性
 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结
构混乱且难以理解。
 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对
象。
 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
 将多个对象间复杂的关联关系解耦,将多个对象间的控制逻辑进行集中
管理。Façade是解耦系统外到系统内(单向)的对象关联关系;
Mediator模式是解耦系统内各个对象之间(双向)的关联关系。
 随着控制逻辑的复杂化,可能需要对Mediator具体对象进行分解处理。
Adapter模式
举例
电源插座在不同国家有多种标准,如国标、美标、英标、南非标、德标、意标等,此外
各国生活用电电压标准也各有不同,如美国的生活用电电压是110V,而中国的电压是
220V。如果要在中国使用美国电器,你有什么好主意吗?
我们有多款OBD设备,协议都各不相同,并且在某些项目中客户还不排除引入第三方
厂商的OBD硬件,我们的OBD核心平台应该采取什么样的设计模式呢?
Adapter模式
动机
 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对
象”放在新的环境中应用,但是新环境要求的接口是这些现存对象
所不满足的。
 如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,
同时又能满足新的应用环境所要求的接口?
意图
 将一个类的接口转换成客户希望的另一个接口。Adapter模式使得
原本由于接口不兼容而不能一起工作的那些类可以一起工作。
Adapter模式
结构
适用性
 你想使用一个已经存在的类,而它的接口不符合你的需求。
 你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的
类(即那些接口可能不一定兼容的类)协同工作。
 (仅适用于对象Adaptor)你想使用一些已经存在的子类,但是不可能
对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父
类接口。
 Adapter模式本身要求我们尽可能地使用“面向接口的编程风格”,这
样才能在后期很方便地适配。
“对象”适配器
推荐
“状态变化”模式
在组件构建过程中,某些对象的状态经常面临变化,如何对这些变
化进行有效的管理?同时又维持高层模块的稳定?“状态变化”模
式为这一问题提供了一种解决方案。
典型模式
 Memento
 State
Memento模式
举例
我们玩单机游戏的时候总会遇到MM大人的各种事情,一会儿陪逛街,一会儿去打个酱
油,会耽误我们玩游戏的进程,但是此时我们能有“保存游戏”这个宝贝,我们的主基
地就不会在我们打酱油的时候被对手拆掉。
“保存游戏”的功能其实就是备忘录模式的很好应用,它在不破坏封装的前提下,捕获
一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以把该对象恢复到
原先保存的状态。
你能想到其它类似的例子吗?
Memento模式
动机
 在软件构建过程中,某些对象的状态在转换过程中,可能由于某种
需要,要求程序能够回溯到对象之前处于某个点时的状态。如果使
用一些公有接口来让其他对象得到对象的状态,便会暴露对象的细
节实现。
 如何实现对象状态的良好保存与恢复?但同时又不会因此而破坏对
象本身的封装性。
意图
 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象
之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状
态。
Memento模式
结构
适用性
 备忘录(Memento)存储原发器(Originator)对象的内部状态,在需
要时恢复原发器状态。适用于“由原发器管理,却又必须存储在原发器
之外的信息”
 要防止原发器以外的对象访问备忘录对象。 备忘录对象有两个接口,一
个为原发器使用的宽接口,一个为其他对象使用的窄接口
 现代语言(如C#、Java等)往往采用效率较高,又较容易正确实现的
序列化方案来实现Memento模式。
State模式
举例
实现G.8032(Ethernet Ring Protection)协议。
State模式
动机
 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而
发生变化,比如文档处于只读状态,其支持的行为和读写状态支持
的行为就可能完全不同。
 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为
对象操作和状态转化之间引入紧耦合?
意图
 允许一个对象在其内部状态改变时改变它的行为。从而使对象看起
来似乎修改了其行为。
State模式
结构
适用性
 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它
的行为。
 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的
状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含
这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。
这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对
象可以不依赖于其他对象而独立变化。
 为不同状态引入不同对象使得状态转换变得更加明确,保证转换原子性
“数据结构”模式
常常有一些组件在内部具有特定的数据结构,如果让客户程序依赖
这些特定的数据结构,将极大地破坏组件的复用。这时候,将这些
特定数据结构封装在内部,在外部提供统一的接口,来实现与特定
数据结构无关的访问,是一种行之有效的解决方案。
典型模式
 Composite
 Iterator
 Chain of Responsibility
Composite模式
举例
你该如何对车网互联的组织架构进行建模呢?
Composite模式
动机
 在某些情况下,客户代码过多地依赖于对象容器复杂的内部实现结
构,对象容器内部实现结构(而非抽象接口)的变化将引起客户代
码的频繁变化,带来了代码的维护性、扩展性等弊端。
 如何将“客户代码与复杂的对象容器结构”解耦?让对象容器自己
来实现自身的复杂结构,从而使得客户代码就像处理简单对象一样
来处理复杂的对象容器?
意图
 将对象组合成树形结构以表示“部分-整体”的层次结构。
Composite使得用户对单个对象和组合对象的使用具有一致性。
Composite模式
结构
适用性
 采用树形结构来实现普遍存在的对象容器,从而将“一对多”的关系转
化为“一对一”的关系,使得客户代码可以一致地处理对象和对象容器,
无需关心处理的是单个的对象,还是组合的对象容器。
 将“客户代码与复杂的对象容器结构”解耦是Composite的核心思想,
解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的内部实现
结构——发生依赖,从而更能“应对变化” 。
 具体实现中,可以让父对象中的子对象反向追溯;如果父对象有频繁的
遍历需求,可使用缓存技巧来改善效率。
Iterator模式
举例
Java集合类有Collection, List, Set, Map等,虽然每种类的细节各有不同,但对于集
合元素的遍历需求是一致的。
public class SimpleCollection{
public static void main(String[] args){
Collection<Integer> c = new ArrayList<Integer>();
for(int i = 0;i < 10; i++)
c.add(i); //Autoboxing
for(Integer i: c)
System.out.println(i +", ");
}
}
Iterator模式
动机
 在软件构建过程中,集合对象内部结构常常变化各异。但对于这些
集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户
代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同
一种算法在多种集合对象上进行操作”提供了可能。
 使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对
变化中的集合对象”提供了一种优雅的方式。
意图
 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该
对象的内部表示。
Iterator模式
结构
适用性
 迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。
 迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持同样
的算法在不同的集合结构上进行操作。
 迭代器的健壮性考虑:遍历的同时更改迭代器所在的集合结构,会导致
问题。
 支持对聚合对象的多种遍历。
Chain of Responsibility模式
举例
以下web.xml看着眼熟吗?Axis等很多系统也有相同的设计,使得编程人员可以灵活增删
和定义自己的处理规则。
<filter>myFilter</filter>
<filter-name>myFilter</filter-name>
<filter-class>xx.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myFilter</filter-name>
<servlet-name>目标资源一</servlet-name>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>myFilter</filter-name>
<servlet-name>目标资源二</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Chain of Responsibility模式
动机
 在软件构建过程中,一个请求可能被多个对象处理,但是每个请求
在运行时只能有一个接受者,如果显式指定,将必不可少地带来请
求发送者与接受者的紧耦合。
 如何使请求的发送者不需要指定具体的接受者?让请求的接受者自
己在运行时决定来处理请求,从而使两者解耦。
意图
 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之
间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,
直到有一个对象处理它为止。
Chain of Responsibility模式
结构
适用性
 应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者
只有一个”,只有这时候请求发送者与接受者的耦合才有可能出现
“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好地应
对变化。
 对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求
的处理职责。
 如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的缺省
机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。
“行为变化”模式
在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变
化。“行为变化”模式将组件的行为和组件本身进行解耦,从而支
持组件行为的变化,实现两者之间的松耦合。
典型模式
 Command
 Visitor
Command模式
举例
在设计界面时,大家可以注意到这样的一种情况,同样的菜单控件,在不同的应用环境
中的功能是完全不同的;而菜单选项的某个功能可能和鼠标右键的某个功能完全一致。
按照最差、最原始的设计,这些不同功能的菜单、或者右键弹出菜单是要分开来实现的,
你可以想象一下,word文档上面的一排菜单要实现出多少个“形似神非”的菜单类来?
这完全是行不通的。这时,就要运用分离变化与不变的因素,将菜单触发的功能分离出
来,而制作菜单的时候只是提供一个统一的触发接口。这样修改设计后,功能点可以被
不同的菜单或者右键重用;而且菜单控件也可以去除变化因素,很大的提高了重用;而
且分离了显示逻辑和业务逻辑的耦合。这便是命令模式的雏形。
Command模式
动机
 在软件构建过程中,“行为请求者”与“行为实现者”通常呈现一
种“紧耦合”。但在某些场合——比如需要对行为进行“记录、撤
销/重(undo/redo)、事务”等处理,这种无法抵御变化的紧耦合
是不合适的。
 在这种情况下,如何将“行为请求者”与“行为实现者”解耦?将
一组行为抽象为对象,可以实现二者之间的松耦合。
意图
 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行
参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
Command模式
结构
适用性
 根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象
语言中,常见的实现手段是“将行为抽象为对象”。
 具体命令对象ConcreteCommand有时候根据需要可能会保存一些
额外的状态信息;可以将多个“命令”封装为一个“复合命
令”MacroCommand。
 与C++函数对象区别:Command以面向对象中的“接口-实现”来定
义行为接口规范,更严格,更符合抽象原则;C++函数对象以函数签
名来定义行为接口规范,更灵活,更高效,但抽象能力比较弱。
Visitor模式
举例
一个集合(Collection)中,可以包含一个Car,也可以包含一个Cat,对于不同类型的元
素,他们的行为也不尽相同,比如,Car可能有start()行为,而Cat可能有eat()的行为。
可是对于Collection来说,不管你是Car,还是Cat,取出来的都是Object,那么我们如何
知道取出来的是什么呢?
我们可能会如下操作:
Iterator itor = collection.iterator();
while(itor.hasNext()){
Object o = itor.next();
if(o instanceof Car){
((Car)o).start();
}else if(o instanceof Cat){
((Cat)o).eat();
}
}
这时你应该可以看出这种方式可能会出现的问题,假如现在Collection中放入了成千上万
个不同类型的对象,也就意味着你需要成千上万个if else。这时,我们是否需要考量一
下,我们的设计…
Visitor模式
动机
 在软件构建过程中,由于需求的改变,某些类层次结构中常常需要
增加新的行为(方法),如果直接在基类中做这样的更改,将会给
子类带来很繁重的变更负担,甚至破坏原有设计。
 如何在不更改类层次结构的前提下,在运行时根据需要透明地为类
层次结构上的各个类动态添加新的操作,从而避免上述问题?
意图
 表示一个作用于某对象结构中的各元素的操作。使得可以在不改变
各元素的类的前提下定义作用于这些元素的新操作。
Visitor模式
结构
适用性
 通过所谓双重分发(double dispatch)来实现在不更改Element类层
次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新
的操作。所谓双重分发即Visitor模式中间包括了两个多态分发:第一个
为accept方法的多态辨析;第二个为visit方法的多态辨析。
 最大缺点在于扩展类层次结构(增添新的Element子类),会导致Visitor
类的改变。适用于“类层次结构稳定,而其中操作经常面临频繁改动”。
“领域问题”模式
在特定领域中,某些变化的频度已经超出了传统的“抽象接口”所
能解决的范围。这时候,结合特定领域,分析领域特点,从而给出
在该领域下的一般性解决方案。
典型模式
 Interpreter
Interpreter模式
举例
(1) 正则表达式;
(2) 规则引擎;
(3) 自动化测试工具;
(4) 医疗项目中对于医院上传Excel文件的内容正确性校验;
(5) … …
Interpreter模式
动机
 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结
构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁
的变化。
 在这种情况下,将特定领域的问题表达为某种语法规则下的句子,
然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。
意图
 给定一个语言,定义它的文法的一种表示,并定义一种解释器,这
个解释器使用该表示来解释语言中的句子。
Interpreter模式
结构
适用性
 应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁
变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”
才适合使用Interpreter模式。使用Interpreter模式来表示文法规则,
从而可以使用面向对象技巧来方便地“扩展”文法。
 比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会
产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工
具。
其它设计模式
结构化分解
 整体-部分模式
工作的组织
 主控-从属模式
访问控制
 代理模式
管理
 命令处理器
 视图处理程序模式
通信
 转发器-接收器模式
 客户机-分配器-服务器模式
 出版者-订阅者模式
 事件通道
《面向模式的软件体系结构 – 卷1 模式系统》
整体-部分模式
意图
 有助于聚合组件形成一种语义单元。一种聚合组件(即整体),封
装其构成组件(即部分),组织它们之间的协作,并为其功能提供
一个公共接口。直接访问各个部分是不可能的。
结构
关联
 Composite模式是整体-部分模式的一个变体
 Façade模式并不强行封装部分-客户机也可以直接访问部分
主控-从属模式
意图
 支持容错性、并行计算以及计算准确性。主控组件将工作分配给相
同的从属组件并从从属组件返回的结果中计算出最终的结果。
结构
关联
 Chain of Responsibility
 Command
 Mediator
代理模式(访问控制)
意图
 使一个组件的客户机与一个组件代表而不是组件本身通信,引入这
样一个占位符有许多用途,包括提高效率、易于存取和防止越权访
问。
结构
关联
 Facade
 Iterator
命令处理器模式
意图
 将一个服务的请求与其执行分开。一个命令处理器组件管理作为独
立对象的请求,调度它们的执行,并且提供额外的服务,例如存储
以后撤销用的请求对象。
结构
关联
 Command
 Memento
View Handler模式
意图
 有助于管理软件系统提供的所有视图。一个视图处理程序组件使得
客户机能够打开、使用和关闭视图。它还协调视图间的依赖关系并
组织它们的更新
结构
Forward-Receiver模式
意图
 为对等交互模型的软件系统提供了透明的进程间通信。它引入转发
器和接收器用于从底层通信机制中分离出对等体。
结构
Client-Dispatcher-Server模式
意图
 在客户机与服务器间引入一个中间层——分配器组件。借助命名服
务实现位置透明性,并且隐藏客户机与服务器间建立通信连接的细
节。
结构
事件通道模式
意图
 由OMG在其事件服务规格说明中提出并且以分布式系统为目标。
严格分理出出版者和订阅者。订阅者不关心到底是哪个组件的数据
被更改了,出版者也不关心哪个组件正在订阅。
结构
更多设计模式…
?
架构模式
(Architecture Styles)
经典的架构模式(分类)
类别 名称 例子
调用-返回
(Call and Return)
分层
(Hierarchical Layer)
OSI 7层网络协议
主程序-子程序
(main program and subroutine)
很多
面向对象(OO systems) 很多
独立组件
(Independent components)
通讯进程(communicating
processes)
某些自控系统
事件系统(event systems)
OS微内核结构
MFC message机制
虚拟机
(Virtual Machine)
解释器(interpreters)
c++ compiler
任天堂模拟器on PC
cpu软件模拟器for嵌入式开发
规则为中心(rule-based systems) 某些人工智能系统
数据流
(Dataflow)
批处理(batch sequential) 某些老式的os
管道-过滤器(pipes and filters)
MS DirectShow
Unix CC(compiler/linker等)
数据为中心
(Data-centered)
数据库(database)
DB2
Oracle
黑板(blackboard) 某些人工智能系统
架构模式的现代分类
类别 名称 特点 例子
从混沌到结构
(From Mud to
Structure)
分层(Layer)
.直观的分而治之方式
.层的重用
.依赖性局部化
.可替代性
通信协议栈
Java虚拟机
很多应用系统
管道-过滤器
(Pipes and Filters)
.重用性好
.便于重组新策略
.交互性差
.适用于复杂处理
编译器
Unix Shell
DirectShow
通信协议解析
黑板(Blackboard)
.算法和数据分离
.耦合度大
.适用于某些AI系统
人工智能系统
分布式系统
(Distributed System)
代理者
(Broker)
.屏蔽复杂性
.支持互操作
.适用于分布式系统
CORBA
RMI
交叉编译系统
交互式系统
(Interactive System)
MVC
(Model-View-Controller)
.灵活性
.广泛流行
很多
PAC
(Presentation-Abstraction-
Control)
.灵活性
.复杂
人工智能系统
适应性系统
(Adaptive System)
微内核
(Microkernel)
.适应变化
.支持长生命周期
.复杂
OS
JBoss
Eclipse
基于元数据
(Meta-Level-Architecture)
.适应变化
.支持长生命周期
.不易实现
反射框架
Spring
MDA
支持把整个系
统任务以受控
方式分解成可
写作的子任务
为分布式应用
提供了一个完
整的基础架构
(涉及到微核、
管道和过滤器
模式)
支持具有人机
交互特征的软
件系统的构建
支持应用的扩
展以及他们对
进化技术和变
更功能需求的
适应性
《面向模式的软件体系结构 – 卷1 模式系统》
常见架构模式
Distributed
Event-driven
Frame-based
Batch
Pipes and filters
Repository-centric
Blackboard
Interpreter
Rule-based
Layered
MVC
IR-centric
Subsumption
Disposal
“从混沌到结构”模式
支持把整个系统任务以受控方式分解成可写作的子任务
典型模式
 Layers
 Pipes and Filters
 Balckboard
Layers模式
Example: OSI 7-Layer Model
Benefits:
Aiding development by teams
(多团队并行开发)
Incremental coding and testing
(增量编码与测试)
Easier exchange of individual
parts(易于替换独立部分)
Reuse of individual layers in
different layers in different
contexts(可以在不同场景下复
用不同分层)
Layers模式
Context:
A large system that requires decomposition(一个需要分解的大系统)
Problem:
Late source code changes should not ripple through the system (changeable)
Interfaces should be stable, and may even be prescribed by a standards body
Parts of the system should be exchangeable
It may be necessary to build other systems at a later date with the same low-level
issues as the system you are currently designing (Reusable)
Similar responsibilities should be grouped to help understandability and
maintainability. But each component should be coherent.
There’s no ‘standard’ component granularity
Complex components need further decomposition
Crossing component boundaries may impede performance
System will be built by a team of programmers and work has to be subdivided along
clear boundaries
Layers模式
Solution
Structure your system into an appropriate number of layers and place them
on top of each other
Start at the lowest level of abstraction (Layer 1), which is the base of your
system
Work your way up the abstraction ladder by putting Layer J on top of Layer J-
1 until you reach the top level of functionality (Layer N)
Above does not prescribe the order in which to actually design layers, it just
gives a conceptual view
Within an individual layer all constituent components work at the same level
of abstraction
Most of the services that Layer J provides are composed of services provided
by Layer J-1. The services of each layer implement a strategy for combining
the services of the layer below in a meaningful way. In addition, Layer J’s
services may depend on other services in Layer J
Layers模式
Structure: by CRC card
The services of Layer J are only used by Layer
J+1 ---- There are no further direct
dependencies between layers
Layers模式
Dynamics
Top-down communication: ‘requests’
Bottom-up communication: ‘notifications’
Requests only travel through a subset of the layers: ‘caching layers’
Notifications only travel through a subset of the layers
Two stacks of N layers communicating with each other
Layers模式
Implementation
Define the abstraction criterion for grouping tasks into layers (定原则)
Determine the number of abstraction levels according to your abstraction
criterion (定分层)
Name the layers and assign tasks to each of them (分任务)
Specify the services (定服务)
Refine the layering (Iterate over steps 1 to 4) (迭代优化)
Specify an interface for each layer (定接口)
Structure individual layers (定层内结构)
Specify the communication between adjacent layers (定通信方式)
Decouple adjacent layers (层间解耦)
Design an error-handling strategy (定错误处理策略)
Layers模式
Example resolved
Layers模式
Variants
Relaxed Layered System: the gain of flexibility and performance is paid for by
a loss of maintainability.
Layering Through Inheritance: higher layers can modify lower-layer services
according to their needs. But such an inheritance relationship closely ties the
higher layer to the lower layer.
Known Uses
Virtual Machines
APIs
Information Systems
Windows NT
Layers模式
Liabilities
Cascades of changing behavior
Lower Efficiency
Unnecessary work
Difficulty of establishing the correct granularity of layers
See also
Composite Message Pattern
Microkernel architecture
PAC architectural pattern
Pipes & Filters模式
Example
Pipes & Filters模式
Context
Processing data streams (处理数据流)
Problem
Future system enhancements should be possible by exchanging processing
steps or by recombination of steps, even by users (支持处理流程更改)
Small processing steps are easier to reuse in different contexts (步骤重用)
Non-adjacent processing steps do not share information
Different sources of input data exist, such as a network connection or a
hardware sensor providing temperature readings, e.g..
It should be possible to present or store final results in various ways
Explicit storage of intermediate results for further processing in files clutters
directories and is error-prone, if done by users
You may not want to rule out multi-processing the steps, for example
running them in parallel or quasi-parallel.
Pipes & Filters模式
Solution
The pipes and filters architectural pattern divides the task of a system into
several sequential processing steps.
These steps are connected by the data flow through the system
Each processing step is implemented by a filter component
A filter consumes and delivers data incrementally to achieve low latency and
enable real parallel processing
The input is provided by a data source such as a text file
The output flows into a data sink such as a file, terminal, animation program and
so on.
The data source, the filters and the data sink are connected sequentially by pipes
Each pipe implements the data flow between adjacent processing steps
The sequence of filters combined by pipes is called processing pipeline
Pipes & Filters模式
Structure
Pipes & Filters模式
Dynamics
Passive filters
Pipes & Filters模式
Dynamics
Active filters
Pipes & Filters模式
Implementation
Divide the system’s task into a sequence of processing stages;(将处理过程
分段)
Define the data format to be passed along each pipe;(定义数据格式)
Decide how to implement each pipe connection;(定义管道连接)
Design and implement the filters;(实现过滤器)
Design the error handling;(实现错误处理)
Set up the processing pipeline;(建立执行管道)
Pipes & Filters模式
Variants
Tee and join pipeline systems;
Known Uses
UNIX pipes and filters;
CMS pipelines;
LASSPTools;
Pipes & Filters模式
Consequences
Benefits:
 No intermediate files necessary, but possible;
 Flexibility by filter exchange;
 Flexibility by recombination;
 Reuse of filter components;
 Rapid prototyping of pipelines;
 Efficiency by parallel processing;
Liabilities:
 Sharing state information is expensive or inflexible;
 Efficiency gain by parallel processing is often an illusion
 The cost for transferring data between filters may be relatively high
 Some filters consume all their input before producing any output
 Context switching between threads or processes
 Synchronization of filters via pipes may stop and start filters often
 Data transformation overhead
 Error Handling
Pipes & Filters模式
See also
The Layers pattern is better suited to systems that require reliable operation,
because it is easier to implement error handling than with Pipes and Filters.
Blackboard模式
Example
Context: An immature domain in which no closed approach to a
solution is known or feasible. (一个不成熟的领域)
Blackboard模式
Problem:
A complete search of the solution space is not feasible in a reasonable time
Since the domain is immature, you may need to experiment with different
algorithms for the same subtask. Individual modules should be easily
exchangeable
There are different algorithms that solve partial problems
Input, as well as intermediate and final results, have different
representations, and the algorithms are implemented according to different
paradigms
An algorithm usually works on the result of other algorithms
Uncertain data and approximate solutions are involved.
Employing disjoint algorithms induces potential parallelism. If possible you
should avoid a strictly sequential solution
Blackboard模式
Solution
Collection of independent programs that work cooperatively on a common
data structure. Each program is specialized for solving a particular part of the
overall task and all programs work together on the solution
A central control component evaluates the current state of processing and
coordinates the specialized programs.
During the problem-solving process the system works with partial solutions
that are combined, changed or rejected. Each of these solutions represents a
partial problem and a certain stage of its solution. The set of all possible
solutions is called the solution space, and is organized into levels of
abstraction.
Blackboard模式
Structure
Divide your system into a component called blackboard, a collection of
knowledge sources and a control component
Blackboard: the central data store. Elements of the solution space and
control data are stored here. The blackboard provides an interface that
enables all knowledge sources to read from and write to it.
Knowledge sources are separate, independent subsystem that solve specific
aspects of the overall problem. Together they model the overall problem
domain. None of them can solve the task of the system alone. Knowledge
sources do not communicate directly – they only read from and write to the
blackboard.
Control: runs a loop that monitors the changes on the blackboard and
decides what action to take next. It schedules knowledge source evaluations
and activations according to a knowledge application Strategy.
Blackboard模式
Structure
Blackboard模式
Dynamic
Blackboard模式
Implementation
Define the problem
Define the solution space of the problem
Divide the solution process into steps
Divide the knowledge into specialized knowledge sources with certain
subtasks
Define the vocabulary of the blackboard
Specify the control of the system. If the control component displays complex
and independent subtasks, define one control knowledge source for each of
these subtasks.
Implement the knowledge sources. Split the knowledge sources into
condition-parts and action-parts according to the needs of the control
component.
Blackboard模式
Variants
Production system [OPS language]
Repository
Known uses
HEARSAY-II
HASP / SIAP
CRYSALIS
TRICERO
Generalizations
SUS
Blackboard模式
Consequences
Help to resolve most of the forces listed in the problem section
Experimentation
Support for changeability and maintainability
Reusable knowledge sources
Support for fault tolerance and robustness
Liabilities
Difficulty of testing
No good solution is guaranteed
Difficulty of establishing a good control strategy
Low efficiency
High development effort
No support for parallelism
“分布式系统”模式
为分布式应用提供了一个完整的基础架构
典型模式
 Pipes and Filters(参见“从混沌到结构”模式)
 Microkernel(参见“适应性系统”模式)
 Broker
Broker模式
Example
Broker模式
Context
Your environment is a distributed and possibly heterogeneous system with
independent cooperating components
Problem
Building a complex software system as a set of decoupled and interoperating
components, rather than as a monolithic application, results in greater
flexibility, maintainability and changeability. By partitioning functionality
into independent components the system becomes potentially distributable
and scalable
Forces
Component should be able to access services provided by others through
remote location-transparent service invocations;
You need to exchange, add, or remove components at run-time
The architecture should hide system – and implementation-specific details from
the users of components and services
Broker模式
Solution
Introduce a broker component to achieve better decoupling of clients and
servers. Server register themselves with the broker, and make their service
available to clients through method interfaces. Clients access the
functionality of servers by sending requests via the broker. A broker’s task
include locating the appropriate server, forwarding the request to the server
and transmitting results and exceptions back to the client.
Broker模式
Structure
Broker模式
Dynamic
Scenario 1: Server Registration
Broker模式
Dynamic
Scenario 2: Client Request
Broker模式
Dynamic
Scenario 3: Interaction of different brokers via bridge components
Broker模式
Implementation
Define an object model, or use an existing model
Decide which kind of component-interoperability the system should offer
Specify the APIs the broker component provides for collaborating with clients and
servers
Use proxy objects to hide implementation details from clients and servers
Design the broker component in parallel with steps 3 and 4
 Specify a detailed on-the-wire protocol for interacting with client-side proxies and server-
side proxies
 A local broker must be available for every participating machine in the network
 When a client invokes a method of a server, the broker system is responsible for returning
all results and exceptions back to the original client
 If the proxies do not provide mechanisms for marshaling and unmarshaling parameters and
results, you must include that functionality in the broker component
 … …
Broker模式
Example Resolved
Variants
Direct Communication Broker System
Message Passing Broker System
Trader System
Adapter Broker System
Callback Broker System
Known Cases
CORBA
IBM SOM/DSOM
Microsoft’s OLE 2.*
WWW
ATM-P
Broker模式
Consequences
Benefits:
 Location Transparency
 Changeability and extensibility of components
 Portability of a Broker system
 Interoperability between different Broker systems
 Reusability
Liabilities
 Restricted efficiency
 Lower fault tolerance
 Testing and Debugging
See also
The Forwarder-Receiver pattern
The Proxy pattern
The Client-Dispatcher-Server pattern
The Mediator design pattern
“交互式系统”模式
支持具有人机交互特征的软件系统的构建
典型模式
 Model-View-Controller(MVC)
 Presentation-Abstraction-Control(PAC)
MVC模式
Example
Content
Interactive applications with a flexible human-computer interface
MVC模式
Problem
Forces:
The same information is presented differently in different windows, for example,
in a bar or pie chart
The display and behavior of the application must reflect data manipulations
immediately
Changes to the user interface should be easy, and even possible at run-time
Supporting different ‘look and feel’ standards or porting the user interface
should not affect code in the core of the application
MVC模式
Solution
MVC divides an interactive application into the three areas
Processing: The model component encapsulates core data and functionality. The
model is independent of specific output representations or input behavior
Output: View components display information to the user. A view obtains the
data from the model. There can be multiple views of the model
Input: Each view has an associated controller component. Controllers receive
input, usually as events that encode mouse movement, activation of mouse
buttons, or keyboard input. Events are translated to service requests for the
model or the view. The user interacts with the system solely through controllers
The change-propagation mechanism for multiple view is described in the
Publisher-Subscriber pattern
MVC模式
Structure
MVC模式
Dynamic
Scenario 1: How user input that results in changes to the model triggers the
change-propagation mechanism
MVC模式
Dynamic
Scenario 2: How the MVC triad is initialized
MVC模式
Implementation
Separate human-computer interaction from core functionality
Implement the change-propagation mechanism
Design and implement the views
Design and implement the controllers
Design and implement the view-controller relationship
Implement the set-up of MVC
Dynamic view creation
‘Pluggable’ controllers
Infrastructure for hierarchical views and controllers
Further decoupling from system dependencies
MVC模式
Variants
Document-View
Known Uses
Smalltalk
MFC
ET++
MVC模式
Consequences
Benefits:
 Multiple views of the same model
 Synchronized views
 ‘Pluggable’ views and controllers
 Exchangeability of ‘look and feel’
 Framework potential
Liabilities
 Increased complexity
 Potential for excessive number of updates
 Intimate connection between view and controller
 Close coupling of views and controllers to a model
 Inefficiency of data access in view
 Inevitability of change to view and controller when porting
 Difficulty of using MVC with modern user-interface tools
See also
The Presentation-Abstraction-Control pattern
MVC模式
Variants
Document-View
Known Uses
Smalltalk
MFC
ET++
PAC模式
Example
Content
Development of an interactive application with the help of PAC agents
PAC模式
Problem
Forces:
Agents often maintain their own state and data. However, individual agents
must effectively cooperate to provide the overall task of the application. To
achieve this, they need a mechanism for exchanging, data, messages, and events.
Interactive agents provide their own user interface, since their respective
human-computer interactions often differ widely.
Systems evolve over time. Their presentation aspect is particularly prone to
change. The use of graphics, and more recently, multimedia features, are
examples of pervasive changes to user interfaces. Changes to individual agents,
or the extension of the system with new agents, should not affect the whole
system.
PAC模式
Solution
Structure the interactive application as a tree-like hierarchy of PAC agents.
There should be one top-level agent, several intermediate level agents, and even
more bottom-level agents. Every agent is responsible for a specific aspect of the
application's functionality, and consists of three components: presentation,
abstraction, and control. The whole hierarchy reflects transitive dependencies
between agents. Each agent depends on all higher-level agents up the hierarchy
to the top-level agent.
The agent's presentation component provides the visible behavior of the PAC
agent. Its abstraction component maintains the data model that underlies the
agent, and provides functionality that operates on this data. Its control
component connects the presentation and abstraction components, and
provides functionality that allows the agent to communicate with other PAC
agents.
The top-level PAC agent provides the functional core of the system; Bottom-level
PAC agents represent self-contained semantic concepts on which users of the
system can act, such as spreadsheets and charts; Intermediate-level PAC agents
represent either combinations of, or relationships between, lower-level agents.
PAC模式
Structure
MVC模式
Dynamic
Scenario 1: Describes the cooperation between different PAC agents when
opening a new bar-chart view of the election data.
PAC模式
Dynamic
Scenario 2: shows the behavior of the system after new election data is
entered, providing a closer look at the internal behavior of the top level PAC
agent.
PAC模式
Implementation
Define a model of the application.
Define a general strategy for organizing the PAC hierarchy.
Specify the top-level PAC agent.
Specify the bottom-level PAC agents.
Specify bottom-level PAC agents for system services.
Specify intermediate-level PAC agents to compose lower-level PAC agents.
Specify intermediate-level PAC agents to coordinate lower-level PAC agents.
Separate core functionality from human-computer interaction.
Provide the external interface.
Link the hierarchy together.
PAC模式
Variants
PAC agent as active objects (multi-threading)
PAC agent as processes (remote)
Known Uses
Network Traffic Management
Mobile Robot
PAC模式
Consequences
Benefits:
 Separation of concern
 Support for change and extension
 Support for multi-tasking
Liabilities
 Increased system complexity
 Complex control component
 Efficiency
 Applicability
See also
The Model-View-Controller pattern
“适应性系统”模式
支持应用的扩展以及他们对进化技术和变更功能需求的适应性
典型模式
 Microkernel
 Reflection
Microkernel模式
Example
OS
Content
The development of several applications that use similar programming
interfaces that build on the same core functionality.
Microkernel模式
Problem
Forces:
The application platform must cope with continuous hardware and software
evolution.
The application platform should be portable, extensible and adaptable to
allow easy integration of emerging technologies.
The applications in your domain need to support different, but similar,
application platforms.
The applications may be categorized into groups that use the same functional
core in different ways, requiring the underlying application platform to
emulate existing standards.
The functional core of the application platform should be separated into a
component with minimal memory size, and services that consume as little
processing power as possible.
Microkernel模式
Solution
Encapsulate the fundamental services of your application platform in a
microkernel component.
The microkernel includes functionality that enables other components running in
separate processes to communicate with each other. It is also responsible for
maintaining system wide resources such as files or processes. In addition, it
provides interfaces that enable other components to access its functionality.
Core functionality that cannot be implemented within the microkernel without
unnecessarily increasing its size or complexity should be separated in internal
servers.
External servers implement their own view of the underlying microkernel. To
construct this view, they use the mechanisms available through the interfaces of
the microkernel. Every external server is a separate process that itself represents
an application platform. Hence, a Microkernel system may be viewed as an
application platform that integrates other application platforms.
Clients communicate with external servers by using the communication facilities
provided by the microkernel.
Microkernel模式
Structure
Microkernel模式
Dynamic
Scenario 1: demonstrates the behavior when a client calls a service of its
external server.
Microkernel模式
Dynamic
Scenario 2: illustrates the behavior of a Microkernel architecture when an
external server requests a service that is provided by an internal server.
Microkernel模式
Implementation
Analyze the application domain.
Analyze external servers.
Categorize the services (semantically-independent).
Partition the categories.
Find a consistent and complete set of operations and abstractions for every
category you identified in step 1.
Determine strategies for request transmission and retrieval.
Structure the microkernel component.
To specify the programming interfaces of the microkernel, you need to decide
how these interfaces should be accessible externally.
The microkernel is responsible for managing all system resources.
Design and implement the internal servers as separate processes or shared
libraries.
Implement the external servers.
Implement the adapters.
Develop client applications or use existing ones for the ready-to-run
Microkernel模式
Variants
Microkernel System with indirect Client-Server connections
Distributed Microkernel System
Known Uses
OSs
Eclipse
Microkernel模式
Consequences
Benefits:
 Portability
 Flexibility and Extensibility
 Separation of policy and mechanism
 Scaleability
 Reliability
 Transparency
Liabilities
 Performance
 Complexity of design and implementation
See also
The Broker pattern for distributed software systems
The Reflection pattern
The Layers pattern
Reflection模式
Example
Context
Building systems that support their own modification a priori.
Reflection模式
Problem
Forces:
Changing software is tedious, error prone, and often expensive.
Adaptable software systems usually have a complex inner structure.
The more techniques that are necessary for keeping a system changeable, such
as parameterization, subclassing, mix-ins, or even copy and paste, the more
awkward and complex its modification becomes.
Changes can be of any scale, from providing shortcuts for commonly-used
commands to adapting an application framework for a specific customer.
Even fundamental aspects of software systems can change, for example the
communication mechanisms between components.
Reflection模式
Solution
Make the software self-aware, and make selected aspects of its structure
and behavior accessible for adaptation and change. This leads to an
architecture that is split into two major parts: a meta level and a base level.
The meta level provides a self-representation of the software to give it
knowledge of its own structure and behavior, and consists of so-called
metaobjects.
The base level defines the application logic. Its implementation uses the
metaobjects to remain independent of those aspects that are likely to change.
An interface is specified for manipulating the metaobjects. It is called the
metaobject protocol (MOP), and allows clients to specify particular changes,
such as modification of the function call mechanism metaobject mentioned
above.
Reflection模式
Structure
Reflection模式
Dynamic
Scenario 1: illustrates the collaboration between base level and meta level
when reading objects stored in a disk file.
Reflection模式
Dynamic
Scenario 2: illustrates
the use of the
metaobject protocol
when adding type
information to the meta
level.
Reflection模式
Implementation
Define a model of the application.
Identify varying behavior.
Identify structural aspects of the system.
Identify system services that support both the variation of application services
identified in step 2 and the independence of structural details identified in step
3.
Define the metaobjects.
Define the metaobject protocol.
Define the base level.
Reflection模式
Variants
Reflection with several meta levels
Known Uses
MIP
OLE 2.0
Reflection模式
Consequences
Benefits:
 No explicit modification of source code
 Changing a software system is easy
 Support for many kinds of change
Liabilities
 Modifications at the meta level may cause damage. The robustness of a metaobject
protocol is therefore of great importance.
 Increased number of components.
 Lower efficiency
 Not all potential changes to the software are supported
 Not all languages support reflection, e.g C++
See also
The Microkernel architecture pattern
更多架构模式…
?
Event-Driven模式
Event-Driven模式
工作的组织
访问控制
练习
练习(1)
以下这段代码有问题吗?怎么修改以达到更好设计?
struct Modem
{
enum Type {hayes, courrier, ernie) type;
};
struct Hayes
{
Modem::Type type;
// Hayes related stuff
};
struct Courrier
{
Modem::Type type;
// Courrier related stuff
};
struct Ernie
{
Modem::Type type;
// Ernie related stuff
};
void LogOn(Modem& m,
string& pno, string& user, string& pw)
{
if (m.type == Modem::hayes)
DialHayes((Hayes&)m, pno);
else if (m.type == Modem::courrier)
DialCourrier((Courrier&)m, pno);
else if (m.type == Modem::ernie)
DialErnie((Ernie&)m, pno)
// ...you get the idea
}
练习(2)
请认真阅读《Design Principles and Design Patterns》一书中关于ISP设计原则
的描述,思考我们在软件开发中存在的问题。
 以下哪种设计更好?为什么?
练习(3)
 下列项目的静态结构组织是否存在问题?怎么解决?
练习(4)
请认真阅读《Design Principles and
Design Patterns》一书中关于包设计原
则的描述,思考我们在静态代码组织
中存在的问题。
 下列项目的静态结构组织是否存在问题?存在什么问题?
svn-trunk/common/util 项目结构示意图
练习(5)
 描述Observer模式是如何实现以下设计原则的?
-- Design Principle: Identify the aspects of your application that vary and separate
them from what stays the same.
-- Design Principle : Program to an interface, not an implementation.
-- Design Principle: Favor composition over inheritance.
阅读材料《Head First Design Patterns》一书中关于Observer模式的讲述,
思考Design Pattern和Design Principle之间的关系。
练习(6)
 用Java写一个Singleton的实现类,注意多线程的影响;
用Java写一个Singleton的模板类,以及一个具体类如何使用该模板类的
例子;
练习(7)
 将左边的设计模式和右边的设计意图相匹配
Pattern
Decorator
Adapter
Facade
Intent
Converts one interface to another
Doesn’t alter the interface, but adds responsibility
Makes an interface simpler
Pattern
Template Method
Strategy
Factory Method
Intent
Encapsulate interchangeable behaviors and use
delegation to decide which behaviro to use
Subclasses decide how to implement steps in an
algorithm
Subclasses decide which concrete classes to create
设计模式是为某一设计意图服务的,不应滥用设计模式。
练习(8)
 阅读《Head First Design Patters》第一章《Intro to Design Patterns》
的内容,回答问题:
为什么说“HAS-A can be better than IS-A”?
练习(9)
 阅读《patterns-example》slides,你能举出每个设计模式在生活中的
一些例子吗?
练习(10)
 谈谈对以下分层结构的理解。
《SOA参考架构分层逻辑示意图》
你以前接触过按照哪些分层原则做的分层?
按数据流和执行过程分层,还是按复用性和复用粒度分层?两者有何区别和
联系?
练习(11)
 阅读《领域驱动设计实例详解》slides的相关内容
(1)在领域驱动设计中主要采用了什么模式?
(2)查阅其它资料,谈谈Repository层和DAOs之间的区别?
(3)结合DDD中CQRS的介绍,谈谈EDA(Event-Driven-
Architecture)架构模式的优点。
练习(12)
 阅读阿里巴巴开源项目Dubbo的介绍
(http://alibaba.github.io/dubbo-doc-static/Home-zh.htm)以及
其它关于SOA知识介绍的材料,谈谈对Broker模式的理解。
参考资料
设计原则
《Design Principles and Design Patterns》, Robert C. Martin
设计模式
《设计模式—可复用面向对象软件的基础》
 历史性巨著,确定了设计模式的地位结构型模式
《Head First – Design Patterns》
 阅读起来很轻松
 对设计模式和设计原则之间的关系阐述非常到位
《反模式:危机中软件,架构和项目的重构》
 听听批评模式/架构滥用的声音吧
架构模式
《面向模式的软件体系结构 – 卷1:模式系统》
 中文版翻译得不算太好,建议看原版
《企业应用架构模式》
 Martin Flow的经典书籍,触发了DDD的灵感
《SOA in Practice: The Art of Distributed System》
 SOA本身就是架构模式的组合运用
重构
《重构 — 改善既有代码的设计》
 软件开发的不朽经典,生动阐述重构原理和具体
做法,普通程序员进阶到编程高手必须修炼的秘
笈
《Refactoring to Patterns》
 通过重构实现模式、趋向模式和去除模式,而不
再是在预先设计中使用模式,也不再过早地在代
码中加入模式。
面向模式的软件体系架构

Más contenido relacionado

La actualidad más candente

金蝶 Togaf 企业架构培训方案
金蝶 Togaf 企业架构培训方案金蝶 Togaf 企业架构培训方案
金蝶 Togaf 企业架构培训方案pdffile
 
赤骥 用户研究入门
赤骥 用户研究入门赤骥 用户研究入门
赤骥 用户研究入门jay li
 
專案管理理論基礎
專案管理理論基礎專案管理理論基礎
專案管理理論基礎黑狗 大
 
University spm ppt1
University spm ppt1University spm ppt1
University spm ppt1huanglab
 
VA/VE在半導體業應用
VA/VE在半導體業應用VA/VE在半導體業應用
VA/VE在半導體業應用5045033
 
Lean startup 精益创业 新创企业的成长思维
Lean startup 精益创业 新创企业的成长思维Lean startup 精益创业 新创企业的成长思维
Lean startup 精益创业 新创企业的成长思维Jie Bao
 
Zhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qconZhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qconYiwei Ma
 
房地产企业的成本管理格局规划与有效管理(讲义)
房地产企业的成本管理格局规划与有效管理(讲义)房地产企业的成本管理格局规划与有效管理(讲义)
房地产企业的成本管理格局规划与有效管理(讲义)Di Ai
 
全面项目化管理
全面项目化管理全面项目化管理
全面项目化管理xobo
 
2.ie培訓教材
2.ie培訓教材2.ie培訓教材
2.ie培訓教材營松 林
 
Scrum 實務超入門
Scrum 實務超入門Scrum 實務超入門
Scrum 實務超入門Yin-Hong Hsu
 
2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生appuniverz
 

La actualidad más candente (20)

CRC Card
CRC CardCRC Card
CRC Card
 
金蝶 Togaf 企业架构培训方案
金蝶 Togaf 企业架构培训方案金蝶 Togaf 企业架构培训方案
金蝶 Togaf 企业架构培训方案
 
赤骥 用户研究入门
赤骥 用户研究入门赤骥 用户研究入门
赤骥 用户研究入门
 
專案管理理論基礎
專案管理理論基礎專案管理理論基礎
專案管理理論基礎
 
University spm ppt1
University spm ppt1University spm ppt1
University spm ppt1
 
Ch12
Ch12Ch12
Ch12
 
VA/VE在半導體業應用
VA/VE在半導體業應用VA/VE在半導體業應用
VA/VE在半導體業應用
 
Lean startup 精益创业 新创企业的成长思维
Lean startup 精益创业 新创企业的成长思维Lean startup 精益创业 新创企业的成长思维
Lean startup 精益创业 新创企业的成长思维
 
Zhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qconZhongxing practice-suchunshan-qcon
Zhongxing practice-suchunshan-qcon
 
Ch15
Ch15Ch15
Ch15
 
Ch06
Ch06Ch06
Ch06
 
Ch16
Ch16Ch16
Ch16
 
房地产企业的成本管理格局规划与有效管理(讲义)
房地产企业的成本管理格局规划与有效管理(讲义)房地产企业的成本管理格局规划与有效管理(讲义)
房地产企业的成本管理格局规划与有效管理(讲义)
 
全面项目化管理
全面项目化管理全面项目化管理
全面项目化管理
 
2.ie培訓教材
2.ie培訓教材2.ie培訓教材
2.ie培訓教材
 
Scrum 實務超入門
Scrum 實務超入門Scrum 實務超入門
Scrum 實務超入門
 
Ch10
Ch10Ch10
Ch10
 
Ch01
Ch01Ch01
Ch01
 
2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生2012/05/23 AU Talk - 讓事情發生
2012/05/23 AU Talk - 讓事情發生
 
Ch05
Ch05Ch05
Ch05
 

Destacado

敏捷开发全景视图(流程、方法和最佳实践)
敏捷开发全景视图(流程、方法和最佳实践)敏捷开发全景视图(流程、方法和最佳实践)
敏捷开发全景视图(流程、方法和最佳实践)Weijun Zhong
 
领域驱动设计与模型驱动开发
领域驱动设计与模型驱动开发领域驱动设计与模型驱动开发
领域驱动设计与模型驱动开发Weijun Zhong
 
Design Process in the Responsive Age
Design Process in the Responsive AgeDesign Process in the Responsive Age
Design Process in the Responsive AgePon Kattera
 
GNU gettext簡介 - 以C語言為範例
GNU gettext簡介 - 以C語言為範例GNU gettext簡介 - 以C語言為範例
GNU gettext簡介 - 以C語言為範例Wen Liao
 
Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)ykdsg
 
Data-Driven Design (MX '10)
Data-Driven Design (MX '10)Data-Driven Design (MX '10)
Data-Driven Design (MX '10)Ryan Freitas
 
Data-Driven Design. You’ve got the data, so, now what? - Aaron Huang - Kontagent
Data-Driven Design. You’ve got the data, so, now what? - Aaron Huang - KontagentData-Driven Design. You’ve got the data, so, now what? - Aaron Huang - Kontagent
Data-Driven Design. You’ve got the data, so, now what? - Aaron Huang - KontagentSociality Rocks!
 
GNU Make, Autotools, CMake 簡介
GNU Make, Autotools, CMake 簡介GNU Make, Autotools, CMake 簡介
GNU Make, Autotools, CMake 簡介Wen Liao
 
設計模式的解析與活用:分析
設計模式的解析與活用:分析設計模式的解析與活用:分析
設計模式的解析與活用:分析Kane Shih
 
Data Driven Design
Data Driven DesignData Driven Design
Data Driven DesignTanya M.
 
Consul First Steps
Consul First StepsConsul First Steps
Consul First StepsMarc Cluet
 
Experiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRubyExperiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRubyMatthew Gaudet
 
JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011Kris Mok
 
從組裝軟體中談談軟體發展管理
從組裝軟體中談談軟體發展管理從組裝軟體中談談軟體發展管理
從組裝軟體中談談軟體發展管理Wen Liao
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript EngineKris Mok
 
Java常见问题排查
Java常见问题排查Java常见问题排查
Java常见问题排查bluedavy lin
 
認試軟體測試的世界 & TDD/BDD 入門
認試軟體測試的世界 & TDD/BDD 入門認試軟體測試的世界 & TDD/BDD 入門
認試軟體測試的世界 & TDD/BDD 入門wantingj
 
CTI103 笔记:文章的表达方式
CTI103 笔记:文章的表达方式CTI103 笔记:文章的表达方式
CTI103 笔记:文章的表达方式Cindy Ong
 
CTI101 笔记:文章的构成要素
CTI101 笔记:文章的构成要素CTI101 笔记:文章的构成要素
CTI101 笔记:文章的构成要素Cindy Ong
 
汉语知识简表(词性,短语,句子成分,复句,修辞)SPM
汉语知识简表(词性,短语,句子成分,复句,修辞)SPM汉语知识简表(词性,短语,句子成分,复句,修辞)SPM
汉语知识简表(词性,短语,句子成分,复句,修辞)SPMLittleBieb12
 

Destacado (20)

敏捷开发全景视图(流程、方法和最佳实践)
敏捷开发全景视图(流程、方法和最佳实践)敏捷开发全景视图(流程、方法和最佳实践)
敏捷开发全景视图(流程、方法和最佳实践)
 
领域驱动设计与模型驱动开发
领域驱动设计与模型驱动开发领域驱动设计与模型驱动开发
领域驱动设计与模型驱动开发
 
Design Process in the Responsive Age
Design Process in the Responsive AgeDesign Process in the Responsive Age
Design Process in the Responsive Age
 
GNU gettext簡介 - 以C語言為範例
GNU gettext簡介 - 以C語言為範例GNU gettext簡介 - 以C語言為範例
GNU gettext簡介 - 以C語言為範例
 
Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)Java线上应用问题排查方法和工具(空望)
Java线上应用问题排查方法和工具(空望)
 
Data-Driven Design (MX '10)
Data-Driven Design (MX '10)Data-Driven Design (MX '10)
Data-Driven Design (MX '10)
 
Data-Driven Design. You’ve got the data, so, now what? - Aaron Huang - Kontagent
Data-Driven Design. You’ve got the data, so, now what? - Aaron Huang - KontagentData-Driven Design. You’ve got the data, so, now what? - Aaron Huang - Kontagent
Data-Driven Design. You’ve got the data, so, now what? - Aaron Huang - Kontagent
 
GNU Make, Autotools, CMake 簡介
GNU Make, Autotools, CMake 簡介GNU Make, Autotools, CMake 簡介
GNU Make, Autotools, CMake 簡介
 
設計模式的解析與活用:分析
設計模式的解析與活用:分析設計模式的解析與活用:分析
設計模式的解析與活用:分析
 
Data Driven Design
Data Driven DesignData Driven Design
Data Driven Design
 
Consul First Steps
Consul First StepsConsul First Steps
Consul First Steps
 
Experiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRubyExperiments in Sharing Java VM Technology with CRuby
Experiments in Sharing Java VM Technology with CRuby
 
JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011
 
從組裝軟體中談談軟體發展管理
從組裝軟體中談談軟體發展管理從組裝軟體中談談軟體發展管理
從組裝軟體中談談軟體發展管理
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Java常见问题排查
Java常见问题排查Java常见问题排查
Java常见问题排查
 
認試軟體測試的世界 & TDD/BDD 入門
認試軟體測試的世界 & TDD/BDD 入門認試軟體測試的世界 & TDD/BDD 入門
認試軟體測試的世界 & TDD/BDD 入門
 
CTI103 笔记:文章的表达方式
CTI103 笔记:文章的表达方式CTI103 笔记:文章的表达方式
CTI103 笔记:文章的表达方式
 
CTI101 笔记:文章的构成要素
CTI101 笔记:文章的构成要素CTI101 笔记:文章的构成要素
CTI101 笔记:文章的构成要素
 
汉语知识简表(词性,短语,句子成分,复句,修辞)SPM
汉语知识简表(词性,短语,句子成分,复句,修辞)SPM汉语知识简表(词性,短语,句子成分,复句,修辞)SPM
汉语知识简表(词性,短语,句子成分,复句,修辞)SPM
 

Similar a 面向模式的软件体系架构

软件设计原则、模式与应用
软件设计原则、模式与应用软件设计原则、模式与应用
软件设计原则、模式与应用yiditushe
 
业务需求分析入门
业务需求分析入门业务需求分析入门
业务需求分析入门zhoujg
 
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)LetAgileFly
 
Our experience to start a startup
Our experience to start a startupOur experience to start a startup
Our experience to start a startupYenwen Feng
 
2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發AgileCommunity
 
2006年招聘试题
2006年招聘试题2006年招聘试题
2006年招聘试题yiditushe
 
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天Gelis Wu
 
The way to continuous delivery
The way to continuous deliveryThe way to continuous delivery
The way to continuous deliveryQiao Liang
 
專案進度追蹤
專案進度追蹤專案進度追蹤
專案進度追蹤黑狗 大
 
极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)Will Huang
 
Asp.net mvc網站的從無到有
Asp.net mvc網站的從無到有Asp.net mvc網站的從無到有
Asp.net mvc網站的從無到有Wade Huang
 
Odoo Development
Odoo DevelopmentOdoo Development
Odoo DevelopmentTsungWei Hu
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文Guo Albert
 
Silverlight 2.0 完全新手學堂,基礎入門 10 大招
Silverlight 2.0 完全新手學堂,基礎入門 10 大招Silverlight 2.0 完全新手學堂,基礎入門 10 大招
Silverlight 2.0 完全新手學堂,基礎入門 10 大招Chui-Wen Chiu
 
03_AI旅宿訂房系統-AI智慧訂房方案
03_AI旅宿訂房系統-AI智慧訂房方案03_AI旅宿訂房系統-AI智慧訂房方案
03_AI旅宿訂房系統-AI智慧訂房方案IttrainingIttraining
 
嵌入式測試驅動開發
嵌入式測試驅動開發嵌入式測試驅動開發
嵌入式測試驅動開發hugo lu
 
我的最小项目管理工具集
我的最小项目管理工具集我的最小项目管理工具集
我的最小项目管理工具集wensheng wei
 
广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化taobao.com
 
信息系统开发平台OpenExpressApp
信息系统开发平台OpenExpressApp信息系统开发平台OpenExpressApp
信息系统开发平台OpenExpressAppzhoujg
 
对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改
对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改
对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改zhaoyulee
 

Similar a 面向模式的软件体系架构 (20)

软件设计原则、模式与应用
软件设计原则、模式与应用软件设计原则、模式与应用
软件设计原则、模式与应用
 
业务需求分析入门
业务需求分析入门业务需求分析入门
业务需求分析入门
 
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
Scrum gathering 2012 shanghai 产品管理及用户体验 分会场:敏捷的hard模式 产品经理视角(窦涵之)
 
Our experience to start a startup
Our experience to start a startupOur experience to start a startup
Our experience to start a startup
 
2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發2014/02: 嵌入式測試驅動開發
2014/02: 嵌入式測試驅動開發
 
2006年招聘试题
2006年招聘试题2006年招聘试题
2006年招聘试题
 
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
Visual studio 2012 與 asp.net 4.5 (新功能與開發介紹) 第一天
 
The way to continuous delivery
The way to continuous deliveryThe way to continuous delivery
The way to continuous delivery
 
專案進度追蹤
專案進度追蹤專案進度追蹤
專案進度追蹤
 
极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)极速 Angular 开发:效能调校技巧 (ngChina 2019)
极速 Angular 开发:效能调校技巧 (ngChina 2019)
 
Asp.net mvc網站的從無到有
Asp.net mvc網站的從無到有Asp.net mvc網站的從無到有
Asp.net mvc網站的從無到有
 
Odoo Development
Odoo DevelopmentOdoo Development
Odoo Development
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文
 
Silverlight 2.0 完全新手學堂,基礎入門 10 大招
Silverlight 2.0 完全新手學堂,基礎入門 10 大招Silverlight 2.0 完全新手學堂,基礎入門 10 大招
Silverlight 2.0 完全新手學堂,基礎入門 10 大招
 
03_AI旅宿訂房系統-AI智慧訂房方案
03_AI旅宿訂房系統-AI智慧訂房方案03_AI旅宿訂房系統-AI智慧訂房方案
03_AI旅宿訂房系統-AI智慧訂房方案
 
嵌入式測試驅動開發
嵌入式測試驅動開發嵌入式測試驅動開發
嵌入式測試驅動開發
 
我的最小项目管理工具集
我的最小项目管理工具集我的最小项目管理工具集
我的最小项目管理工具集
 
广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化广告投放代码和创意代码持续优化
广告投放代码和创意代码持续优化
 
信息系统开发平台OpenExpressApp
信息系统开发平台OpenExpressApp信息系统开发平台OpenExpressApp
信息系统开发平台OpenExpressApp
 
对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改
对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改
对“新软攀峰”官网项目中面向对象设计原则和包设计原则的分析与修改
 

面向模式的软件体系架构

Notas del editor

  1. OCP是终极目标,其它几条可以看成是OCP的实现方法。 Abstraction is the key to OCP: 1)动态多态(继承) 2) 静态多态(模板)
  2. Abstraction is the key to OCP: 1)动态多态(继承) 2) 静态多态(模板)
  3. Abstraction is the key to OCP: 1)动态多态(继承) 2) 静态多态(模板)
  4. 1) 远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表。 NEXTSTEP[Add94] 使用N X P r o x y 类实现了这一目的。Coplien[Cop92] 称这种代理为“大使” (A m b a s s a d o r )。 2 )虚代理(Virtual Proxy )根据需要创建开销很大的对象。在动机一节描述的I m a g e P r o x y 就是这样一种代理的例子。 3) 保护代理(Protection Proxy )控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。例如,在C h o i c e s 操作系统[ C I R M 9 3 ]中K e m e l P r o x i e s 为操作系统对象提供 了访问保护。 4 )智能指针(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。 它的典型用途包括: -- 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为S m a r tP o i n t e r s[ E d e 9 2 ] )。 -- 当第一次引用一个持久对象时,将它装入内存。 -- 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。
  5. 其它例子:SVN
  6. A user asks the presentation component of the view coordinator agent to open a new bar chart. The control of the view coordinator agent instantiates the desired bar-chart agent. The view coordinator agent sends an 'open' event to the control component of the new bar-chart agent. The control component of the bar-chart agent first retrieves data from the top-level PAC agent. The view coordinator agent mediates between bottom and top-level agents. The data returned to the barchart agent is saved in its abstraction component. Its control component then calls the presentation component to display the chart. The presentation component creates a new window on the screen, retrieves data from the abstraction component by requesting it from the control component, and finally displays it within the new window.
  7. The user enters new data into a spreadsheet. The control component of the spreadsheet agent forwards this data to the top-level PAC agent. The control component of the top-level PAC agent receives the data and tells the top-level abstraction to change the data repository accordingly. The abstraction component of the top-level agent asks its control component to update all agents that depend on the new data. The control component of the top-level PAC agent therefore notifies the view coordinator agent. The control component of the view coordinator agent forwards the change notification to all view PAC agents it is responsible for coordinating. As in the previous scenario, all view PAC agents then update their data and refresh the image they display.
  8. The user wants to read stored objects. The request is forwarded to the read () procedure of the persistence component, together with the name of the data file in which the objects are stored. Procedure read () opens the data file and calls an internal Readobject() procedure which reads the first type identifier. Procedure readObject () calls the metaobject that is responsible for the creation of objects. The 'object creator' metaobject instantiates an 'empty' object of the previously-determined type. It returns a handle to this object and a handle to the corresponding run-time type information (RTTI) metaobject. Procedure readobject () requests an iterator over the data members of the object to be read from its corresponding metaobject. The procedure iterates over the data members of the object. Procedure readobject ( ) reads the type identifier for the next data member. If the type identifier denotes a built-in type--a case we do not illustrate--the readobject ( ) procedure directly assigns the next data item from the file to the data member, based on the data member's size and offset within the object. Otherwise readobject () is called recursively. This recursion starts with the creation of an 'empty' object if the data member is a pointer. If not, the recursively called readobject ( ) operates on the existing layout of the object that contains the data member. After reading the data, the read ( ) procedure closes the data file and returns the new objects to the client that requested them.