UML第二部分和创建型模式2.0

UML第二部分

一、交互视图

交互视图描述了执行系统功能的各个角色之间相互传递信息的顺序关系。交互视图显示跨越了多个对象的系统控制流程。交互视图可用两种视图来表示:顺序图和协作图,它们各有不同的侧重点。
1:顺序图
顺序图描述的是一个事务的流程,这个流程和面向过程编程中的顺序结构是一样的,从上到下。
2:协作图
协作图是对在一次交互中有意义的对象和对象间的链建模,对象和关系只有在交互的语境中才有意义。协作图用几何排列来表示交互作用中的各角色。附在类元角色上的箭头表示消息,消息的发生顺序用编号数字表示。

二、状态机视图

状态机视图是一个类对象可能经历的的所有历程的模型图。状态机由对象的各个状态和连接这些状态的转换组成。每个状态对一个对象在其生命周期中满足某种条件的一段时间段建模。当一个事件发生时触发状态的转换,从一个状态转化为另一个状态。
这个状态机我认为最好参考一下设计模式里面的状态模式,状态模式的实现就是这个状态图的代码描述。

三、活动视图

活动视图是状态机的一种变体,用来描述执行算法的工作流程中涉及到的活动。活动状态代表了一个活动:一个工作流执行步骤或一个操作的执行。活动图描述了一组顺序的或并发的活动。活动视图用活动来体现。
这个与状态机还是有很大的变化的,它是一个线性的执行步骤,状态机是一种环形触发的情况。状态机是每种情况很复杂,有一定触发状态存在于其中。活动图可能没有这些,但是符合现实的工作流程。

 

创建型模式


一、Singleton单件 模式分类

1)Singleton模式中的实例构造器可以设置为protected以允 许子类派生。
(2)Singleton模式一般不要支持ICloneable接口,因为这可能 会导致多个对象实例,与Singleton模式的初衷违背。
(3) Singleton模式一般不要支持序列化,因为这也有可能导致 多个对象实例,同样与Singleton模式的初衷违背。
(4) Singletom模式只考虑到了对象创建的管理,没有考虑对 象销毁的管理。就支持垃圾回收的平台和对象的开销来
讲,我们一般没有必要对其销毁进行特殊的管理。
(5)不能应对多线程环境:在多线程环境下,使用Singleton模 式仍然有可能得到Singleton类的多个实例对象。

二、Abstract Factory 抽象工厂

• 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂 完全可以。
• “系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
• Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
• Abstract Factory模式经常和Factory Method模式共同组合 来应对“对象创建”的需求变化。

 三、Builder 生成器

• Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
• 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
• Abstract Factory模式解决“系列对象”的需求变 化,Builder模式解决“对象部分”的需求变化。Builder模式通常和Composite模式组合使用。


四、Factory Method 工厂方法

• Factory Method模式主要用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的脆弱。
• Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
• Factory Method模式解决“单个对象”的需求变化,Abstract Factory 模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。


五、Prototype 原型

• Prototype模式同样用于隔离类对象的使用者和具 体类型(易变类)之间的耦合关系,它同样要求 这些“易变类”拥有“稳定的接口”。
• Prototype模式对于“如何创建易变类的实体对象” 采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
• Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法或者序列化 来实现深拷贝。


六、Adapter 适配器

 适配,即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。

• Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况” ,在遗留代码复用、类库迁移等方面非常有用。

• GoF 23 定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
• Adapter模式可以实现的非常灵活,不必拘泥于Gof23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
• Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。

七、Bridge 桥接

• Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有 的绑定关系,使得抽象(Tank的型号)和实现(不同的平台)可以沿着各自的维度来变化。

• 所谓抽象和实现沿着各自纬度的变化,即“子类化”它们,比如不同的Tank型号子类,和不同的平台子类)。得到各个子类之后,便可以任意组合它们,从而获得不同平台上的不同型号。

• Bridge模式有时候类似于多继承方案,但是多继承方案往往违 背单一职责原则(即一个类只有一个变化的原因),复用性比 较差。Bridge模式是比多继承方案更好的解决方法。

• Bridge模式的应用一般在“两个非常强的变化维度”,有时候即使 有两个变化的维度,但是某个方向的变化维度并不剧烈——换言之两个变化不会导致纵横交错的结果,并不一定要使用Bridge模式.

八、 Composite 组合

• Composite模式采用树形结构来实现普遍存在的对象容器,从而将“一 对多”的关系转化为“一对一”的关系,使得客户代码可以一致地处理对 象和对象容器,无需关心处理的是单个的对象,还是组合的对象容器。

• 将“客户代码与复杂的对象容器结构”解耦是Composite模式的核心思 想,解耦之后,客户代码将与纯粹的抽象接口——而非对象容器的复 内部实现结构——发生依赖关系,从而更能“应对变化”。

• Composite模式中,是将“Add和Remove等和对象容器相关的方法”定 义在“表示抽象对象的Component类”中,还是将其定义在“表示对象容 器的Composite类”中,是一个关乎“透明性”和“安全性”的两难问题, 需要仔细权衡。这里有可能违背面向对象的“单一职责原则”,但是对 于这种特殊结构,这又是必须付出的代价。ASP.NET控件的实现在这 方面为我们提供了一个很好的示范。

• Composite模式在具体实现中,可以让父对象中的子对象反向追溯; 如果父对象有频繁的遍历需求,可使用缓存技巧来改善效率。

九、Decorator 装饰

• 通过采用组合、而非继承的手法, Decorator模式实现了在运行时动 态地扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了 单独使用继承带来的“灵活性差”和“多子类衍生问题”。

• Component类在Decorator模式中充当抽象接口的角色,不应该去实 现具体的行为。而且Decorator类对于Component类应该透明——换 言之Component类无需知道Decorator类,Decorator类是从外部来扩 展Component类的功能。

• Decorator类在接口上表现为is-a Component的继承关系,即 Decorator类继承了Component类所具有的接口。但在实现上又表现 为has-a Component的组合关系,即Decorator类又使用了另外一个 Component类。我们可以使用一个或者多个Decorator对象来“装饰”一 个Component对象,且装饰后的对象仍然是一个Component对象。 • Decorator模式并非解决“多子类衍生的多继承”问题,Decorator模式 应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰” 的含义。

十、Façade外观

• 从客户程序的角度来看, Facade模式不仅简化了整个组 件系统的接口,同时对于组件内部与外部客户程序来说, 从某种程度上也达到了一种“解耦”的效果——内部子系统 的任何变化不会影响到Façade接口的变化。

• Façade设计模式更注重从架构的层次去看整个系统,而 不是单个类的层次。Façade很多时候更是一种架构设计 模式。

• 注意区分Façade模式、Adapter模式、Bridge模式与 Decorator模式。Façade模式注重简化接口,Adapter模式 注重转换接口,Bridge模式注重分离接口(抽象)与其实 现,Decorator模式注重稳定接口的前提下为对象扩展功 能。

十一、Flyweight享元

• 面向对象很好地解决了抽象性的问题,但是作为一个运行 在机器中的程序实体,我们需要考虑对象的代价问题。 Flyweight设计模式主要解决面向对象的代价问题,一般不 触及面向对象的抽象性问题。

• Flyweight采用对象共享的做法来降低系统中对象的个数, 从而降低细粒度对象给系统带来的内存压力。在具体实现 方面,要注意对象状态的处理。

• 对象的数量太大从而导致对象内存开销加大——什么样的 数量才算大?这需要我们仔细的根据具体应用情况进行评 估,而不能凭空臆断。

十二、Proxy代理

• “增加一层间接层”是软件系统中对许多复杂问题 的一种常见解决方法。在面向对象系统中,直接 使用某些对象会带来很多问题,作为间接层的 proxy对象便是解决这一问题的常用手段。

• 具体proxy设计模式的实现方法、实现粒度都相差 很大,有些可能对单个对象做细粒度的控制,如 copy-on-write技术,有些可能对组件模块提供抽 象代理层,在架构层次对对象做proxy。

• Proxy并不一定要求保持接口的一致性,只要能够 实现间接控制,有时候损及一些透明性是可以接 受的。

十三、Template Method模板方法

• Template Method模式是一种非常基础性的设计模式,在 面向对象系统中有着大量的应用。它用最简洁的机制(虚 函数的多态性)为很多应用程序框架提供了灵活的扩展 点,是代码复用方面的基本实现结构。

• 除了可以灵活应对子步骤的变化外, “不要调用我,让我 来调用你 ”的反向控制结构是Template Method的典型应用。

• 在具体实现方面,被Template Method调用的虚方法可以 具有实现,也可以没有任何实现(抽象方法、纯虚方 法),但一般推荐将它们设置为protected方法。

上一篇:【设计模式达摩院】03 装饰者模式本质内涵b


下一篇:JavaScript 装饰器Decorator