GRASP原则心得

1.什么是grasp原则

GRASP(General Responsibility Assignment Software Pattern)是通用职责分配软件设计模式。
它由《UML和模式应用》(Applying UML and Patterns)一书作者Craig Larman提出。在面向对象设计的过程中一般的通用方式是构思对象的职责、角色和协作。通常来说,我们在编码过程中先分析问题域,从中抽象出对象解决问题。简单的面向对象和优良的面向对象设计的区别在于将如何更合理的划分对象的角色,给对象赋予合理的职责以及对象之间的交互关系。

2.GRASP的九个原则

信息专家原则(information expert)

信息专家模式的本质指的是我们应该将职责委托给哪一个对象,这个职责可以是一个方法,也可以是一个算法或者其他内容。它是面向过程设计过程中最基本的原则。

委托原则:我们在设计对象的时候,如果某个对象拥有完成某个职责所需要的所有信息,那么这个职责就分配给这个对象实现。这个时候,这个类就是相对于这个职责的信息专家。

示例:我们在设计购物网站的时候,为避免重复,一种商品只能在购物车中出现一次,如果多次出现,则需要将其数量增加。这个时候我们在将物品放入购物车的时候,要首先判断当前物品是否在购物车中,判断两个物品是否为同一个物品的方法这个职责应该委托给谁呢?显而易见,商品类中有唯一标识,所以这个职责由商品类实现,而不是购物车。

创造者原则(creator)

creator原则的本质是创建类对象职责应该委托给那个对象,也就是谁应该负责产生某个类的实例。

解决方案: 如果符合下面的一个或者多个条件,则可以将创建A的实例的职责分配给B;

  • B包含A
  • B聚合A
  • B拥有初始化A的数据并在创建A的实例时将数据传递给A
  • B记录A的实例
  • B频发使用A

满足上述一种或者多种情况的时候,我们应该奖创建A的实例的职责分配给B。

合理的creator原则带来的优点:如果职责分配合理,设计就能降低耦合,提高设计的清晰度,封装性和重用性。

示例:例如订单和商品的关系是聚合关系,这个时候我们将在订单中创建商品。

低耦合(Low coupling)

耦合是评价一个系统中各个元素之间连接或者依赖关系强弱的尺度。低耦合的原则是我们在设计系统的时候尽量降低系统中各个元素之间的耦合度,这样对于系统的理解和维护都有很大的益处。

耦合性高的系统会带来的坏处:

  • 一个类的修改导致其他类产生较大的影响;
  • 系统难以维护和理解;
  • 系统的重用性差,在重用一个高耦合类的时候,不得不重用它所依赖的所有类。

两个类具有以下特性中的其中一个,我们就说这两个类是耦合的:

  • A具有一个类型为B的属性;
  • A调用B的方法
  • A的方法包含对B的引用(参数或者返回值的方式)
  • A是B的直接或者间接的子类
  • A是接口B的一种实现

低耦合系统的设计方法

  • 在类的划分上,尽量创建松耦合的类,类之间的耦合性越低,越有利于复用,修改一个类不会影响其他类。
  • 在类的设计上,尽量降低类中成员和方法的访问权限。
  • 在类的设计上,尽量将类设计为不变类
  • 在类的引用上,将一个对象对另一个对象的引用降低到最小

高内聚(high cohesion)

内聚是评价一个对象的职责被关联的尺度或者强弱,也可以说是功能性内聚的职责。也就是功能性紧密的相关职责应该放在同一个类中,并共同完成有限的功能。这样做更加有利于对类的理解和重用,也可以降低类的维护成本。

往往低内聚的系统设计会导致类的混乱,当对功能进行扩展或者改进的时候带来不必要的麻烦,低内聚的类也不利于重用,因为他们的职责如此之混乱。

为了达到高内聚,我们需要对类的职责进行分解,使分解出来的类具有独立的职责,满足单一职责原则。将一些需要在多个类中使用到的方法封装到一个类中,其他的类只负责他们需要负责的相关功能,这样我们可以提高类的内聚程度。

控制器原则(controller)

控制器模式的实质是将一些系统事件的接受和处理委托给一个的对象controller,这个对象可以是一个类,系统或者子系统,它不与UI进行交互,它只负责系统信息的接收和处理。

一般情况下,控制器是一个系统,这个系统中包括多个处理器,分别对应处理不同的事务。通常情况下,一个控制器应当把要完成的功能委托给其他对象,而它只负责任务的协调控制和分配。

控制器原则与MVC模式相对应,MVC模式是一种比设计模式更高的架构模式。

多态原则(polymorphism)

多态原则与面向对象设计原则中的多态概念类似,这里不再详细赘述。

纯虚构(pure Fabrication)

纯虚构原则与我们所说的纯虚函数类似。

  纯虚构的作用是用来解决高内聚和低耦合之间的矛盾的。高内聚低耦合是我们系统设计的终极目标,高内聚意味着我们要将类拆分成多个功能集中的类,但是拆分的多个类之间需要进行协作才能正常工作,这样又增加了类之间的耦合性。

  纯虚构原则是用来解决上述问题的方案。它要求将一部分类的职责转移到纯虚构类中,在理想的情况下,分配给这种虚构类的职责是为了达到高内聚低耦合的效果。在实际的操作过程中,纯虚构类的实现又很多种方式,例如将数据库中操作的方法从数据库实体中分离出来,形成专门的数据访问类;通过对类的分解来实现类的重用,新增加的数据访问类对应于数据的持久化存储,这是软件开发过程中为了方便虚构出来的一个概念。一般情况下,纯虚构模式通常基于功能进行划分的。

中介模式(indirect)

中介模式的目的是为了避免两个对象之间产生直接耦合,降低对象之间的耦合度。

解决方案是建立中间对象来协调两个对象之间的交互,避免耦合性过高。

受保护模式(protected variations)

受保护模式的实质与OCP(开放闭合原则)类似,我们首先找到系统中不稳定的变化点,使用统一的接口封装起来,如果未来发生变化的时候,可以通过扩展接口来扩展新的功能,而不需要改变旧的代码。这样达到易于扩展的目的。

3.回答设计模式怎样解决问题的

寻找合适的对象

面向对象程序由对象组成,对象包括数据和对数据进行操作的过程,过程通常称为方法或操作。

对象在收到客户的请求(或消息)后,执行相应的操作。

客户请求是使对象执行操作的唯一方法,操作又是对象改变内部数据的唯一方法。

由于这些限制,对象的内部状态是被封装的,它不能被直接访问,它的表示对于对象外部是不可见的。

面向对象设计最困难的部分是将系统分解成对象集合。

因为要考虑许多因素:封装、粒度、依赖关系、灵活性、性能、演化、复用等,它们都影响着系统的分解,并且这些因素通常还是互相冲突的。

设计的许多对象来源于现实世界的分析模型。但是,设计结果所得到的类通常在现实世界中并不存在,有些是像数组之类的低层类,而另一些则层次较高。

设计模式帮你确定并不明显的抽象和描述这些抽象的对象。例如,描述过程或算法的对象现实中并不存在,但它们却是设计的关键部分。

描述对象的实现

对象通过实例化类来创建,此对象被称为该类的实例。

抽象类(Abstract Class)的主要目的是为它的子类定义公共接口。

一个抽象类将把它的部分或全部操作的实现延迟到子类中,因此,一个抽象类不能被实例化。

子类能够重定义(override)父类定义的操作,重定义使得子类能接管父类对请求的处理操作。

类继承允许你只需简单的扩展其他类就可以定义新类,从而可以很容易地定义具有相近功能的对象族。

类继承根据一个对象的实现定义了另一个对象的实现。简而言之,它是代码和表示的共享机制。

接口继承(或子类型化)描述了一个对象什么时候能被用来替代另一个对象。

尽管大部分程序设计语言并不区分类继承和接口继承,但使用中人们还是分别对待它们的。

面向对象的设计原则:针对接口编程,而不是针对实现编程。

运用复用机制

面向对象系统中功能复用的两种最常用技术室类继承和对象组合(Object Composition)。

类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用(White-Box Reuse)。

新的更复杂的功能可以通过组装或组合对象来获得。这种复用风格被称为黑箱复用(Black-Box Reuse)。因为对象的内部细节是不可见的。

父类通常至少定义了部分子类的具体表示。因此继承对子类揭示了其父类的实现细节,所以继承常被认为“破坏了封装性”。

一个可用的解决方法就是只继承抽象类,因为抽象类通常提供较少的实现。

对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口。

因为对象只能通过接口访问,所以我们并不破坏封装性。

使用对象组合有助于保持每个类被封装并被集中在单个任务上,这样类和类继承层次会保持较小规模。

4.在实际编程中,应该怎么选择设计模式?或者如何使用?

运用设计模式,首先我们需要了解什么是设计模式,有哪些常用的设计模式;然后再去看开源框架、造轮子,去真正理解别人是如何运用设计模式的,以及为什么要在这里运用这个设计模式;最后将设计模式运用到我们自己的代码里。看懂源代码,甚至发现框架的设计还不是最好的。这个时候,可以尝试去造轮子,造轮子的过程是吸收别人优秀的设计,去掉别人不足的地方,最后最好再加上自己的创新。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值