首页 > 代码库 > 设计模式后的设计理念:需求变化,针对接口编程,优先使用聚合

设计模式后的设计理念:需求变化,针对接口编程,优先使用聚合

模式的基本元素:模式的名称,该模式所能解决的问题(模式应用的场景),解决方案,使用该模式后的结果(包括优点和缺点)

模式的分类:

架构模式:架构模式描述了软件系统基本的结构组织策略,实际上就是关于软件的宏观组织的规则和指南

设计模式:设计模式描述的是在软件系统的某一局部不断重现的核心解决方案,这种解决方案以完善的设计结构出现,可以被应用到以后出现的类似的语境中

通用职责分配软件模式(GRASP模式):描述了在面向对象设计过程中把职责分配给系统中不同对象的有效经验和基本原则,GRASP模式只是对职责分配过程中的设计原则的总结和概括,而没有为每一个模式提供建议的具体机构

蕴含在设计模式中的设计原则和理念:

  • 设计模式最根本的意图是适应需求变化:易变性根本就是软件的一个内在的特征;设计模式最大的用途就是适应需求变化,在设计模式的帮助下,我们可以在设计阶段就为未来可能发生的变化留下足够的空间(具体见下面机器人喂猪的案例);只实现你需要的东西,并在这一原则的指导下适度使用设计模式,应该把设计模式的应用范围限制在系统中那些明显不稳定,极有可能变化的部分
  • 针对接口编程,而不是针对实现编程:针对接口编程的组件不需要知道对象的具体类型和实现,只需要知道抽象类定义了那些接口,这减少了实现上的依赖关系
  • 优先使用聚合而不是继承

机器人喂猪案例:

一开始养猪场打算用机器人来喂大白猪:


需求变化一:后来引进了长白猪:


现在的问题就是养猪场的需求不断变化的问题,加入有引进了其他种类的猪或者其他的物种,需要不断修改代码;这是就应该添加一个猪的抽象接口,并且修改猪机器人的代码,使其不考虑猪的类型,只应用抽象的猪的接口来操作所有猪的对象实例


需求变化二:让机器人来打扫猪舍(这可能隐藏了更多的变化的需求,未来机器人的功能还可能不断增加,)

更改一:


但是这里存在一个问题:图中的继承结构是在编译器件就确定了的,在运行期不能发生任何变化,因此,如果养猪场需要一个喂猪机器人和一个清洁机器人,那么必须在养猪场放进这两个具体的机器人,以此类推,如果未来养猪场还需要其他种类机器人时,对象数目很大,而且没添加一种机器人就必须修改代码中的某一个地方,

更改二:


继承和聚合的比较:

  • 继承反映的是类之间的“‘.......是一个.......”这样的关系,它在编译期间静态定义,继承的优点是使用起来比较简单,但是缺点是:不能再运行期间改变继承的结构,基类中往往定义了部分的实现,基类的实现暴露给派生类后,继承机制就会破坏数据和操作的封装,使派生类对基类产生的较强的依赖(相对于聚合而言,该使用还是要使用的)
  • 聚合反映的是类之间“.................有一个.....”的关系,是在运行期间动态定义的,因此被聚合对象的类型可以很容易地在运行期间发生变化,只要保证他们的接口相同,满足完全替换原则即可,而且使用聚合可以更好地封装对象, 使每一个类集中在单个职能上,类的继承层次也会保持较小的规模;缺点是他不是面向对象语言直接支持的一个特性,用户必须编写一些代码来完成聚合功能
  • 在不违反继承和聚合所反映的关系的前提下,应该优先使用聚合而不是继承,同时,聚合也必须和接口及相关的继承结构协同使用

设计模式后的设计理念:需求变化,针对接口编程,优先使用聚合