• 24.GRASP模式


    一:GRASP软件开发模式

    <1>Craig Larman在《Applying UML and Patterns》一书中提出了GRASP设计模式的概念。

    <2>作者称其为设计模式,其实,更好的理解应该为设计原则

    <3>GoF设计模式是针对特定问题而提出的解决方法。

    <4>GRASP则是站在面向对象设计的角度,告诉我们怎么样设计问题空间中的类与它们的行为责任,以及明确类之间的相互关系等等。

    <5>GRASP可以说是GoF等设计模式的基础。

    <6>GRASP:
    General Responsibility Assignment Software patterns
    通用职责分配软件模式

    <7>核心思想:
    “职责分配(Responsibility Assignment)”
    用职责设计对象:"Designing Objects with Responsibilities“

    <8>进一步理解核心思想:
    自己干自己的事(职责的分配)
    自己干自己的能干的事(职责的分配)
    自己只干自己的事(职责的内聚)

    五个基本模式

    1、信息专家(Information expert)
    2、创建者(Creator)
    3、高内聚(High Cohesion)
    4、低耦合(Low coupling)
    5、控制器(Controller)

    四个扩展模式

    6、多态性(Polymorphism)
    7、纯虚构(Pure Fabrication)
    8、间接性(Indirection)
    9、防止变异(Protected Variations)

    二:信息专家(Information expert)

    GRASP模式中解决类的职责分配问题的最基本的模式。

    问题
    当我们为系统发现完对象和职责之后,职责的分配原则(职责将分配给哪个对象执行)是什么?

    解决方案
    1、职责的执行需要某些信息(information),把职责分配给该信息的拥有者。换句话说,某项职责的执行需要某些资源,只有拥有这些资源的对象才有资格执行职责。 --“有能者为之”

    2、满足了面向对象设计的封装性的设计,一般情况下都会满足Information Expert模式。因为Information Expert是对类的属性(信息),以及对类的属性的操作的封装,它符合对象封装性的概念。

    优点
    1、信息的拥有者类同时就是信息的操作者类,可以减少不必要的类之间的关联。
    2、各类的职责单一明确,容易理解。

    三:创建者(Creator)

    GRASP模式中解决类的实例的创建职责问题的模式。

    问题
    类的实例的创建职责,应该分配给什么样的类?或者说类的实例应该由谁创建?

    解决方案
    以下条件之一为真的情况,类A的实例的创建职责就分配给类B。
    1、B包含A
    2、B聚集A
    3、B记录A
    4、B频繁使用A
    5、B有A初始化数据

    提倡类的实例(对象)创建职责由聚集或包含该对象的对象创建

    优点
    1、整个结构清晰易懂
    2、有利于类或组件的重用
    3、防止职责的分散
    4、降低耦合性

    四:高内聚(High Cohesion)

    GRASP模式中为降低类的复杂程度,简化控制而提出的面向对象设计的原则性模式。高内聚(High Cohesion)与低耦合(Low Coupling)模式是GRASP其他模式的根本。

    问题
    怎么做才能降低类的复杂程度,简化控制?

    解决方案
    紧密相关的功能(职责)应该分配给同一个类。–“各司其职”

    所谓内聚,是指单个物体(类)内部的功能聚集度。比如,只包含有相互关联的功能的类,具有高内聚性,同时,它的外部表现(作用,意图)也就明显;反之,如果一个类由一些不相关的功能构成,它的内聚性就低,它的外部表现就不明显,一方面很难理解它的作用和意图,另一方面,一旦需求变化,扩展性就差。

    优点
    1、聚集相关功能,结构清晰,容易理解
    2、只聚集相关功能,使得类的职责单一明确,从而降低类的复杂程度,使用简单

    五:低耦合(Low coupling)

    GRASP模式中为降低类的复杂程度,简化控制而提出的面向对象设计的原则性模式。高内聚(High Cohesion)与低耦合(Low Coupling)模式是GRASP其他模式的根本。

    问题
    怎么做才能降低类之间关联程度,能适应需求的变化呢?

    解决方案
    为类分配职责时,应该尽量降低类之间的关联关系(耦合性)。亦即,应该以降低类之间的耦合关系作为职责分配的原则。

    所谓耦合,是指多个物体(类)之间的物理或者意思上的关联程度。在面向对象方法中,类是最基本的元素,耦合主要指不同类之间相互关联的紧密程度。面向对象里的关联,主要指一个类对另一个类的调用,聚合(包含),参数传递等关系。比如,所谓2个关联得非常紧密的类(高耦合),是指其中一个类发生变化(修改)时,另一个类也不得不跟着发生变化(修改)。

    面向对象设计要求类之间满足“低耦合”原则,它是衡量一个设计是否优良的的一个重要标准,因为“低耦合”有助于使得系统中某一部分的变化对其它部分的影响降到最低程度。

    优点
    1、一方面,高内聚要求把紧密关联的功能(职责)聚集在同一个类中,防止功能的扩散和类的无谓增加,从而减少类之间的关联,降低类之间的发生耦合的机率。

    2、另一方面,高内聚要求把不相关的功能分散到不同的类,类增加了,势必造成相互关联类的增加,从而增大类之间发生耦合的机率。

    六:控制器(Controller)

    GRASP模式中解决事件处理职责问题的模式。

    问题
    在UI层之外,应该由哪个类来处理(控制)系统操作(事件)呢?或者说,当触发一个系统事件时,应该把对事件的处理职责分配给UI层之外的哪个类呢?

    解决方案
    把系统事件的处理职责分配给Controller(控制器)类。

    Controller模式提倡用一个专门的类来处理所有的系统事件。或者说Controller模式把所有系统事件的处理职责分配给一个专门的类集中处理。

    优点
    1、防止同类职责的分散。满足高内聚,低耦合原则。
    2、有利于共通处理(前处理,后处理等)。
    3、变化的高适应能力。能够把变化的修改范围控制在最小范围(控制器)之内。

    七:多态性(Polymorphism)

    问题
    如何处理基于类型的选择?如何创建可插拔的软件构件?

    解决方案
    当相关选择或行为随类型(类)有所不同时,使用多态操作为变化的行为类型分配职责。

    八:纯虚构(Pure Fabrication)

    问题
    当你并不想违背高内聚和低耦合或其它目标,但是基于专家模式所提供的方案又不合适时,哪些对象应该承担这一职责?(很多情况下,只对领域对象分配职责会导致不良内聚或耦合,或者降低复用潜力)

    解决方案
    对人为制造的类分配一组高内聚的职责,该类并不代表问题领域的概念——虚构的事物,用以支持高内聚,低耦合和复用。

    所有GOF设计模式(或其它模式)都是纯虚构。

    九:间接性(Indirection)

    问题
    为了避免两个或多个事物之间的直接耦合,应该如何分配职责?如何使对象解耦合,以支持低耦合并提供复用性潜力?

    解决方案
    将职责分配给中介对象,避免它们之间的直接耦合。中介实现了间接性。
    大量GOF模式,如适配器、外观等等都是间接性的体现。

    十:防止变异(Protected Variations)

    问题
    如何设计对象、子系统和系统,使其内部的变化或不稳定性不会对其它元素产生不良影响?

    解决方案
    识别预计变化或不稳定之处,分配职责用以在这些变化之外创建稳定接口。

    几乎所有的软件或架构设计技巧,都是防止变异的特例,比如封装、多态、接口、虚拟机、配置文件等。

    十一:防止变异的核心机制

    1、数据驱动设计(Data-Driven Design):通过外置、读取并判断变化因素,防止数据、元数据或说明性变量等对系统产生影响。
    2、服务查询(Service Lookup):Data-Driven Design的特例,如JNDI,UDDI,通过使用查询服务的稳定接口,客户能够避免服务位置变化的影响。
    3、解释器驱动的设计(Interpreter-Driven Design):系统通过外置、读取、解释逻辑而避免了逻辑变化的影响。
    4、反射或元级的设计(Reflective or Meta-Level Design)可避免逻辑或外部代码变化的影响
    5、统一访问(Uniform Access):如C#中的XXX.Name
    6、标准语言(Standard Language)
    7、Liskov替换原则(LSP):在对T有任何替换实现或子类(成为S)情况下,引用类型T(某接口或抽象超类)的软件(方法,类……)应该正常或按照预期工作。
    8、得墨忒耳定律(Law of Demeter):不要经历远距离的对象结构路径去向远距离的间接对象发送消息。
    9、开放-封闭原则(OCP):模块应该同时(对扩展、可适应性)开放和(对影响客户的更改)封闭。

    十二:GRASP软件开发模式-总结

    GRASP和GoF都是称为软件开发模式,只是描述的内容和角度不同。

    GRASP和GoF是不同类型的模式,出发点不同。GRASP是解决类之间如何交互,如何设计合理,和具体问题无关。

    GoF往往是解决一些具体的问题,比如类的具体创建方式等等,而GRASP是解决对象分析的一些基本原则,即你如何去设计你的问题空间中的类和它们的行为,是原则性的东西。

    GRASP适用于对象分析和设计中,即在RUP的制作分析模型和设计模型阶段,GoF更适用于在实际编码过程中作为更加具体的指导思想。

  • 相关阅读:
    WhatsApp群发系统-SendWS拓客系统功能后台介绍(五):WhatsApp筛号群发,群发超链
    上周热点回顾(8.1-8.7)
    六、python Django REST framework GET参数处理[过滤、排序、分页]
    图解java.util.concurrent并发包源码系列——各种各样的阻塞队列BlockingQueue一套带走(ノ`Д)ノ!!!
    d中声明式gui
    驱动中获取设备树节点信息
    【数据结构】6.1 二叉树(C语言)
    How To Improve Your LISTENING SKILLS( 如何提升你的听力技能) 学习
    LVGL_基础控件timer
    【MPC】③二次规划求解器quadprog的win平台下C++动态库生成与使用
  • 原文地址:https://blog.csdn.net/zzyzxb/article/details/126855397