亲宝软件园·资讯

展开

《UML与设计原则》--第四小组

软件第四小组 人气:0

 

关于设计模式与原则

一、设计模式简介

  设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案。而面向对象设计模式描述了面向对象设计过程中特定场景下、类与相互通信的对象之间常见的组织关系。

二、GoF 23种设计模式

该模式是学习面向对象设计模式的起点。但并非终点。也并非其就表示了所有的“面向对象设计模式”。

三、面向对象设计模式

      面向对象设计模式解决的是“类与相互通信的对象之间的组织关系”,包括它们的角色、职责、协作方式几个方面。

      面向对象设计模式是“好的面向对象设计”,所谓“好的面向对象设计”是那些可以满足“应对变化,提高复用”的设计。

      面向对象设计模式描述的是软件设计,因此它是独立于编程语言的,但是面向对象设计模式的最终实现仍要使用面向对象编程语言来表达

▲从宏观层面看,面向对象的构建方式更能适应软件的变化,能将变化所带来的影响减为最小。

从微观层面来看,面向对象的方式更强调各个类的责任,新增成员类型不会影响原来员工类型的实现代码。

四、面向对象的三大特征

    1、封装:隐藏内部实现  

     2、继承:复用现有代码   

     3、多态:改写对象行为

五、对象

     从概念层面讲,对象是某种拥有责任的抽象。

     从规格层面讲,对象是一系列可以被其他对象使用的公共接口。

     从语言实现层面来看,对象封装了代码和数据。

   ▲怎样才能设计“好的面向对象”?

     遵循一定的面向对象设计原则。

     熟悉一些典型的面向对象设计模式。

六、设计模式的三大原则

1、针对接口编程,而不是针对实现编程    客户不需要知道使用对象的特定类型,只需要知道对象拥有客户所期望的接口。

2、优先使用对象组合,而不是类继承    继承在某种程度上破坏了封装性,子类父类耦合度高;而对象组合则只要求被组合的对象具有良好定义的接口,耦合度低。

3、封装变化点,封装的代码不会影响其他代码, 实现城市间的松耦合。

▲敏捷软件开发实践提倡的是“Perfactoring to Patterns”是目前普遍公认的最好的使用设计模式的方法。

七、设计原则(5个)

1.单一职责原则(SRP)   

   一个类应该仅有一个引起它变化的原因(只有一个引起变化的原因)

2.开放封闭原则(OCP)    

   类模块应该是可扩展的,但是不可修改(对扩展开放,对更改封闭)

3.Liskov替换原则(LSP)    

   子类必须能够替换他们的基类

4.依赖倒置原则(DIP)   

   高层模块不应该依赖于底层模块,二者都不应该依赖于抽象    

   抽象不应该依赖于实现细节,实现细节应该依赖于抽象

5.接口隔离原则(ISP)   

   不应该强迫客户程序依赖于他们不用的方法

▲最好的面向对象设计模式:减少修改,提高复用。

关于设计模式之禅

 1.设计模式可以提高代码的可重用性,增强系统的可维护性。

 2.设计原则(6个):

    1>单一职责原则(SRP):仅有一个能引起类变更的原因。 重点:划分职责

      优点:(1)类的复杂度降低,职责清晰明了。

            (2)可读性提高

            (3)可维护性提高

            (4)变更的影响范围小,如果每个接口的职责做得好,那么其中一个接口的修改不会影响其他接口,只会影响实现类,有利于扩展和维护。

      适用:适用于接口,类,方法

      建议:接口做到单一职责,类的设计尽量做到只有一个原因引起变化。例如:有一个接口IPhone,里面有IPhone的行为和逻辑,这时应该把行为和逻辑分开,这样有一个接口只负责接电话,挂电话,有一个接口负责通话。

    2>里氏替换原则(LSP):父类出现的地方,子类可以进行替换,反之,子类出现的地方,父类不适应。

      优点:增强程序健壮性。

      适用:方法

      注意:

      1》在类中调用其他类时,务必要使用父类或接口,如果不能使用父类或接口,则说明类的设计违背了LSP原则。

      2》如果子类不能完整地实现父类的方法,或者父类的某些方法在子类已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。

      3》覆盖或实现父类的方法时,分为两种情况:重写时,输入参数要相同,范围值要小于或等于父类的类型;重载时,输入参数的类型和个数可以不同,输入参数的类型要比父类的输入参数类型宽泛,否则将违反里氏替换法则。

      4》采用里氏替换法则时,尽量避免子类的“个性”。

 

    3>依赖倒置(核心是面向接口编程)原则(DIP):高层模块不依赖与低层模块,二者都应依赖于抽象。抽象不依赖于实现细节,实现细节依赖于抽象。  目的:使类或模块之间实现独立,不互相影响。

      名词解释:低层模块是不可分割的原子逻辑,高层模块是原子逻辑的再组装。实现细节是抽象接口/抽象类的实现子类。

      优点:减少耦合性,提高系统的稳定性,降低风险,提高可读性和可维护性。

      注意:

      1》判断设计是否具有稳定性,要看无论处于什么环境下,都可以做到不改动。

      2》依赖的三种写法:

         构造函数传递依赖对象、settter方法传递依赖对象、接口声明传递依赖对象

      3》如何使用依赖倒置原则(DIP)呢?

          1)每个类应具备接口、抽象类其中的一种或两种。

          2)变量的编译时类型尽量是接口或抽象类。

          3)不要从具体类去派生类,尽量不要覆盖父类的方法

          4)结合里氏替换原则使用

       

    4>接口隔离原则(ISP):对接口进行细化,保证其纯洁性。接口中的方法尽量要少。减少与外界的交互,提高接口的自处理能力。定义接口中的方法时要考虑角色,为每个角色定制独有的服务,避免出现风险。接口的数量要根据实际情况进行创建。

      适用:类、接口

      --1》接口和类尽量适用原子接口和原子类来组装,原子的划分规则有哪些呢?

           一个接口只负责服务一个子模块或业务逻辑。

           尽量减少接口中的方法。

           尽量去修改被污染的接口,如果风险较大,建议采用适配器模式处理。

           深入了解业务逻辑,分析项目环境,拒绝盲从。

           实践+经验+领悟,才能做到接口隔离原则。

      注意:根据接口隔离原则拆分接口时,首先必须满足单一职责原则。

 

       

    5>迪米特法则(LOD):一个方法尽量不引入本类中不存在的对象。不向其他对象暴露自身的信息,仅提供一些公有方法来与外界联系,这样,需要更改时,仅修改本类,不会影响其他类。需要注意的是,公有方法越多,要修改的地方越多。

      注意:

      1》如果一个方法放在本类中,既不增加类间关系,也不对本类产生负面影响,就放置在本类中。

      2》谨慎使用Serializable

      3》谨慎使用迪米特法则,使用迪米特法则,将会增加跳转次数,提高维护的困难性。

    6>开闭原则(是所有原则中最基础,最重要的)(OCP):对扩展开放,对修改关闭

      适用:类、模块、抽象、方法

      优点:

        简化测试代码

        提高复用性

        提高可维护性

      注意:

       1》对货币进行处理时,一般取2位精度。通常做法:运算时扩大100倍,展示时缩小100倍。

       2》应对变化时,通常考虑三种方案:修改接口,修改实现类,通过扩展实现变化

       3》变化有三种类型:

           *逻辑变化

           *子模块变化

           *可见视图变化

       4》实现项目的过程:

         项目开发->重构(对原有的设计和代码进行修改)->测试->投产->运维(尽量减少对原有代码的修改,提高系统的稳定性)

 

小小结:

    1.设计之初,就要考虑到所有可能变化的因素,然后留下接口,做到未雨绸缪。

    2.怎样约束一组可能变化的行为呢?

      1>通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法。

      2>参数类型、引用对象尽量使用接口或者抽象类,而不是实现类。

      3>抽象层尽量保持稳定,一旦确定将不允许修改。

    3.怎样减轻编程的压力?

     尽量使用配置参数来控制程序的行为,减少重复开发。

    4.23种设计模式都是从各个不同的角度对变化进行封装的。23种设计模式并非要我们严格地去执行,只是按照原则那样做会增强维护性,提高拓展性和健壮性,23种设计模式并非短时间内即可练成,它需要项目经验的累积,也需要我们花时间多去揣摩,领悟,感受其优点,更需要我们坚持下去。

关于UML

1.什么是UML(统一建模语言)呢?

   统一建模语言是一种直观化、明确化、构建和文档化软件系统产物的通用可视化建模语言。优点:捕捉了被构建系统的有关决策和理解,用来理解、设计、浏览、配置、维护以及控制系统的信息。

 2.UML的功能?

   1>捕捉系统静态结构(需要哪些对象)和动态行为(对象之间的交互)的信息。系统建模成独立对象的集合,它们互相交互以实现功能,从而最终使外部使用者获益。

   2>用包来分解模型的组织性结构。允许将系统分为一个个工作单元,理解包之间的依赖关系,并在复杂的环境下对每个单元进行管理。

   3>对软件、硬件、数字逻辑的离散系统进行建模。

 3.UML的目标有哪些?

   1>使UML成为一个通用的建模语言,供所有的建模者使用。

   2>使UML支持所有的,至少支持目前现有的大部分软件升发过程。

   3>尽可能简洁的同时,能够对实际需要建立的系统的各个方面建模。

 4.概念和模型划分的范围:

   1》静态结构:是首先定义的,必须首先定义讨论的各种事物,即应用中的关键概念,他们的内部特征和相互之间的关系。

   2》动态行为:指的是相互连接的对象交互实现行为,即依赖上下文的对象和互相之间链的视图,连同对象间数据链上的消息流。建模行为分为两种方式:(1)通过与外界交互的对象的生命史。(2)使用一系列对象的通信方式。

   3》实现构造:描述了运行系统中结点的配置,构件和对象在结点中的分部,以及结点内容的可能迁移。

   4》模型组织:将模型内容组织到适度大小的包中,包是模型中通用的层次结构。

   5》扩展机制:扩展机制包括版型、约束、标签值。版型也称类型、构造型,它是对一个UML元素基础定义的扩展,在同一个元素基础定义的基础上赋予特别的含义,使得这个元素适用于特定的场合。约束是一个可打包的元素,它表示与某个元素(拥有约束)或多个元素相关的某些条件、约束或断言。约束通常由布尔表达式指定。标签值可以存储任何元素的信息。

 5.视图是什么?视图在最高层次划分的三个领域是什么?这三个领域分别是什么意思?

   视图是表达系统单个方面的建模结构的简单子集。

   视图在最高层次领域分为三部分:结构性分类、动态管理、模型管理。

   结构性分类描述的是系统中事物与事物之间的关系,分类视图包括静态视图、用例视图、实现视图。

   动态行为描述了系统上的行为,行为视图包括状态视图、活动图、交互图(分为顺序图、协作图)。

   模型管理描述了用层次式单元对模型自身的组织,有模型管理视图。

   视图还包括扩展,扩展包括约束、版型、标签值。

 6.静态视图:

   静态视图相当于概念建模,定义了单个快照(系统的例子)中可以存在的一系列对象、值和链。是其他视图构建的基础,主要组成部分是分类和各种关系(关联、继承、依赖)。分类是描述事物的模型元素,包括类、接口、数据类型、用例、活动者、构件、结点、子系统。  显示为类图

  类:建模中的离散概念,包括状态和行为。状态由属性和关联组成,行为表现为操作,方法是操作的实现。对象的生命周期由状态机表示。类用具有类名称、属性、操作分隔的长方形表示。类的容器是包,单子类只有一个实例。类有三种:分析层的,设计层的,实现层的。

   接口:接口是未实现行为的描述,包含操作。

   数据类型:是对无标识的基本数据的描述。包括数字、字符串、枚举值。

   类间的关系是连接类的途径,根据关系上线的结构和路径或端点上的修饰来区分关系。

 

   类图中的关系:

   

     依赖:依赖绘制成从源头到目标头的虚线箭头,使用版型来区分类型。

7.用例视图:

  用例视图从外部用户的角度捕获系统、子系统或类的行为,通过系统与一个或多个活动者之间的一系列消息描述了与活动者的交互。

  作用:列举活动者和用例,显示活动者在每个用例中的参与情况。

  用例:是系统单元提供的外部可感知的功能单元。用例用椭圆表示,用例名称在椭圆中或下方,用实线与同自身通信的活动者相连接。

  活动者:是系统、子系统或类交互的外部人员、进程或事务的理想化。活动者用一个小人和名称来表示。

  用例关系的种类:

     关联:用实线表示,表示活动者和用例之间的通信路径。

     扩展:用虚线带关键字《extend》表示,表示额外行为的插入,基用例对插入不知情。

     用例概括:用实线带空心箭头表示,表示一般用例与更具体化用例之间的关系,更加特定用例继承一般用例并添加特性。

     包含:用虚线带关键字《include》表示,表示附加行为的至基用例的显式插入。

  包含和扩展关系:用带关键字《include》和《extend》的虚线绘制。包含关系执行被包含的用例;扩展关系执行被扩展的用例。

8.交互视图:

 交互视图描述了系统行为角色之间的消息交换序列,目的:定义清晰的行为块。

 用两种图来显示:1.顺序图(显示用例的行为序列)  2.协作图(对交互中存在意义的对象和链建模)。

 顺序图强调时间顺序,协作图强调各个角色之间的关系。

9.状态机视图:显示类的对象的生命历程,将对象的生命历程转换为对应的状态,当事件执行后,状态也会随之更新。初始状态一般为黑点。

10.活动视图:显示执行某个运算过程中的运算活动的一种变形。动作的输入和输出参数可以显示成连接动作的流关系和对象流状态。

11.物理视图:(对概念进行建模)对应用本身的实现结构建模。物理视图分为两种 :实现视图、配置视图。

实现视图对模型中的构建建模。显示为构件图。接口显示为具有名称的圆,连接构件与接口的实线表示构件能向接口提供的服务,而虚线则表示构件需要接口提供的服务。

配置视图对构件在结点中的分布建模。显示为配置图。

12.模型管理视图:对模型本身的组织建模。模型由包含模型元素(如类、状态机、用例)的包构成。每个模型元素被包或其他元素所拥有。特殊的包有两个:模型(描述系统整体视图的包),子系统。

 

 

加载全部内容

相关教程
猜你喜欢
用户评论