UML第二部分
一、交互视图
交互视图描述了执行系统功能的各个角色之间相互传递信息的顺序关系。交互视图显示跨越了多个对象的系统控制流程。交互视图可用两种视图来表示:顺序图和协作图,它们各有不同的侧重点。
1:顺序图
顺序图描述的是一个事务的流程,这个流程和面向过程编程中的顺序结构是一样的,从上到下。
2:协作图
协作图是对在一次交互中有意义的对象和对象间的链建模,对象和关系只有在交互的语境中才有意义。协作图用几何排列来表示交互作用中的各角色。附在类元角色上的箭头表示消息,消息的发生顺序用编号数字表示。
二、状态机视图
状态机视图是一个类对象可能经历的的所有历程的模型图。状态机由对象的各个状态和连接这些状态的转换组成。每个状态对一个对象在其生命周期中满足某种条件的一段时间段建模。当一个事件发生时触发状态的转换,从一个状态转化为另一个状态。
这个状态机我认为最好参考一下设计模式里面的状态模式,状态模式的实现就是这个状态图的代码描述。
三、活动视图
活动视图是状态机的一种变体,用来描述执行算法的工作流程中涉及到的活动。活动状态代表了一个活动:一个工作流执行步骤或一个操作的执行。活动图描述了一组顺序的或并发的活动。活动视图用活动来体现。
这个与状态机还是有很大的变化的,它是一个线性的执行步骤,状态机是一种环形触发的情况。状态机是每种情况很复杂,有一定触发状态存在于其中。活动图可能没有这些,但是符合现实的工作流程。
创建型模式的总结(2-6讲)
创建型模式
一、Singleton单件 模式分类
从目的来看:
1.创建型(Creational)模式:负责对象创建。
2.结构型(Structural)模式:处理类与对象间的组合。
3.行为型(Behavioral)模式:类与对象交互中的职责分配。
从范围来看:
1.类模式处理类与子类的静态关系。
2.对象模式处理对象间的动态关系。
动机(Motivation)
在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。
意图(Intent)
保证一个类仅有一个实例,并提供一个该实例的全局访问点。——《设计模式》
单线程Singleton模式的几个要点:
(1)Singleton模式中的实例构造器可以设置为protected以允 许子类派生。
(2)Singleton模式一般不要支持ICloneable接口,因为这可能 会导致多个对象实例,与Singleton模式的初衷违背。
(3) Singleton模式一般不要支持序列化,因为这也有可能导致 多个对象实例,同样与Singleton模式的初衷违背。
(4) Singletom模式只考虑到了对象创建的管理,没有考虑对 象销毁的管理。就支持垃圾回收的平台和对象的开销来
讲,我们一般没有必要对其销毁进行特殊的管理。
(5)不能应对多线程环境:在多线程环境下,使用Singleton模 式仍然有可能得到Singleton类的多个实例对象。
Singleton模式扩展:
(1)将一个实例扩展到n个实例,例如对象池的实现。
(2) 将new 构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。
(3)理解和扩展Singleton模式的核心是“如何控制用户使用new对一个类的实例构造器的任意调用”。
二、Abstract Factory 抽象工厂
1、new的问题
常规的对象创建方法:
// 创建一个Road 对象
Road road=new Road();
new的问题:
– 实现依赖,不能应对“具体实例化类型”的变化。
解决思路:
– 封装变化点 —— 哪里变化,封装哪里
– 潜台词:如果没有变化,当然不需要额外的封装!
2、工厂模式的缘起
? 变化点在“对象创建”,因此就封装“对象创建”
? 面向接口编程——依赖接口,而非依赖实现
? 最简单的解决方法:
class RoadFactory {
public static Road CreateRoad()
{
return new Road();
}
}
// 创建一个Road 对象
Road road=
roadFactory.CreateRoad();
3、Abstract Factory模式的几个要点
? 如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂 完全可以。
? “系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
? Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
? Abstract Factory模式经常和Factory Method模式共同组合 来应对“对象创建”的需求变化。
三、Builder 生成器(创建型模式)
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 ——《设计模式》
Builder 模式的几个要点:
? Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
? 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
? Abstract Factory模式解决“系列对象”的需求变 化,Builder模式解决“对象部分”的需求变化。Builder模式通常和Composite模式组合使用。
四、Factory Method 工厂方法
1、从耦合关系谈起,耦合关系直接决定着软件面对变化时的行为。
– 模块与模块之间的紧耦合使得软件面对变化时,相关的模块都要随之更改。
– 模块与模块之间的松耦合使得软件面对变化时,一些模块更容易被替换或者更改,但其他模块保持不变。
2、意图(Intent)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟到子类。 ——《设计模式》
3、Factory Method模式的几个要点:
? Factory Method模式主要用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系会导致软件的脆弱。
? Factory Method模式通过面向对象的手法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
? Factory Method模式解决“单个对象”的需求变化,Abstract Factory 模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。
五、Prototype 原型
1、依赖关系的倒置
– 抽象
抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
2、意图(Intent)
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。 ——《设计模式》
3、Prototype模式的几个要点:
? Prototype模式同样用于隔离类对象的使用者和具 体类型(易变类)之间的耦合关系,它同样要求 这些“易变类”拥有“稳定的接口”。
? Prototype模式对于“如何创建易变类的实体对象” 采用“原型克隆”的方法来做,它使得我们可以非常灵活地动态创建“拥有某些稳定接口”的新对象——所需工作仅仅是注册一个新类的对象(即原型),然后在任何需要的地方不断地Clone。
? Prototype模式中的Clone方法可以利用.NET中的Object类的MemberwiseClone()方法或者序列化 来实现深拷贝。
4、有关创建性模式的讨论
? Singleton模式解决的是实体对象个数的问题。除了Singleton之外,其他创建型模式解决的都是new所带来的耦合关系。
? Factory Method, Abstract Factory, Builder都需要 一个额外的工厂类来负责实例化“易变对象”,而Prototype则是通过原型(一个特殊的工厂类)来 克隆“易变对象”。
? 如果遇到“易变类”,起初的设计通常从FactoryMethod开始,当遇到更多的复杂变化时,再考虑重构为其他三种工厂模式
(Abstract Factory,Builder, Prototype )。
补充:《C#面向对象设计模式纵横谈》第一部分——面向对象设计模式与原则
设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案。
面向对象设计模式描述了面向对象设计过程中、特定场景下、类与相互通信的对象之间常见的组织关系。
1、设计模式与面向对象
? 面向对象设计模式解决的是“类与相互通信的对象之间的组织关系,包括它们的角色、职责、协作方式几个方面。
? 面向对象设计模式是“好的面向对象设计”,所谓“好的面向对象设计”是那些可以满足“应对变化,提高复用”的设计 。
? 面向对象设计模式描述的是软件设计,因此它是独立于编程语言的,但是面向对象设计模式的最终实现仍然要使用面向对象编程语言来表达,本课程基于C#语言,但实际上它适用于支持.NET框架的所有.NET语言,如Visual Basic.NET、C++/CLI等。
? 面向对象设计模式不像算法技巧,可以照搬照用,它是建立在对“面向对象”纯熟、深入的理解的基础上的经验性认识。掌握面向对象设计模式的前提是首先掌握“面向对象”!
2、从编程语言直观了解面向对象
? 各种面向对象编程语言相互有别,但都能看到它们对面向对象三大机制的支持,即:“封装、继承、多态”
– 封装,隐藏内部实现
– 继承,复用现有代码
– 多态,改写对象行为
? 使用面向对象编程语言(如C#),可以推动程序员以面向对象的思维来思考软件设计结构,从而强化面向对象的编程范式。
? C#是一门支持面向对象编程的优秀语言,包括:各种级别的封装支持;单实现继承+多接口实现;抽象方法与虚方法重写。
但OOPL并非面向对象的全部
? 通过面向对象编程语言(OOPL)认识到的面向对象,并不是面向对象的全部,甚至只是浅陋的面向对象。
? OOPL的三大机制 “封装、继承、多态” 可以表达面向对象的所有概念,但这三大机制本身并没有刻画出面向对象的核心精神。换言之, 既可以用这三大机制做出 “好的面向对象设计”,也可以用这三大机制做出 “差的面向对象设计”。不是使用了面向对象的语言(例如C#),就实现了面向对象的设计与开发!因此我们不能依赖编程语言的面向对象机制,来掌握面向对象。
3、重新认识面向对象
对象是什么?
– 从概念层面讲,对象是某种拥有责任的抽象。
– 从规格层面讲,对象是一系列可以被其他对象使用的公共接口。
– 从语言实现层面来看,对象封装了代码和数据。
4、从设计原则到设计模式
? 针对接口编程,而不是针对实现编程– 客户无需知道所使用对象的特定类型,只需要知道对象拥有客户所期望的接口。
? 优先使用对象组合,而不是类继承– 类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。继承在某种程度上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。
? 封装变化点– 使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。
? 使用重构得到模式——设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷 软件开发实践提的“Refactoring to Patterns”是目前普遍公认的最好 的使用设计模式的方法。
5、几条更具体的设计原则
? 单一职责原则(SRP):– 一个类应该仅有一个引起它变化的原因。
? 开放封闭原则(OCP):– 类模块应该是可扩展的,但是不可修改(对扩展开放,对更改封闭)
? Liskov 替换原则(LSP):– 子类必须能够替换它们的基类
? 依赖倒置原则(DIP):– 高层模块不应该依赖于低层模块,二者都应该依赖于抽象。– 抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
? 接口隔离原则(ISP):– 不应该强迫客户程序依赖于它们不用的方法。
6、总结
设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案。面向对象设计模式描述了面向对象设计过程中、特定场景下、类与相互通信的对象之间常见的组织关系。
? 深刻理解面向对象是学好设计模式的基础,掌握一定的面向对象设计原则才能把握面向对象设计模式的精髓,从而实现灵活运用设计模式。
? 三大基本面向对象设计原则
– 针对接口编程,而不是针对实现编程
– 优先使用对象组合,而不是类继承
– 封装变化点
? 使用重构得到模式。敏捷软件开发实践提倡的“Refactoring toPatterns”是目前普遍公认的最好的使用设计模式的方法。
原文:https://www.cnblogs.com/xjbb/p/14377086.html