4.9 在实现语义约束时,最好根据类定义来实现。但是这经常会导致泛滥成灾的类,在这种情况下约束应当在类的行为中实现,通常在类的构造函数中实现,但不是必须如此。

还是以汽车为例,我们看汽车的定义,为了集中注意力,先只关心汽车的发动机

  1. class 汽车
  2. {
  3. 汽车(发动机 para)
  4. {
  5. m_发动机=para;
  6. }
  7. 发动机 m_发动机;
  8. }
  9. class 发动机{...}

我们可以定义奥迪A6,凯梅瑞等等汽车

  1. class 奥迪A6:汽车{......}
  2. class 凯梅瑞:汽车{......}

同样我们可以定义丰田发动机,三菱发动机等等

  1. class 丰田发动机:发动机{......}
  2. class 三菱发动机:发动机{......}

问题,假设奥迪A6只能使用丰田发动机,凯梅瑞只能使用三菱发动机,问题是汽车只包含了抽象的发动机,对抽象的汽车类来说,所有发动机没有任何区别,那么需要我们把这个 约束条件放到合适的位置。

首先我们考虑在构造函数中加以约束,那么奥迪A6,凯梅瑞汽车的构造函数就分别如下:

  1. 奥迪A6(丰田发动机 para):base(para){}
  2. 凯梅瑞(三菱发动机 para):base(para){}

这种方式很可靠,能保证系统里不会出现状态非法的汽车(奥迪A6使用了三菱发动机,就是非法状态)

这种方式的问题在于,如果汽车和发动机的种类繁多,会导致出现泛滥成灾的类。

第二种方式,我们不保证汽车的状态合法,而是在汽车的行为里检查,状态是不是合法。

我们看看汽车的启动方法,可以如下定义

  1. class 汽车
  2. {
  3. 。。。。。。
  4. void 启动()
  5. {
  6. //先检查汽车的状态,如果状态不合法,则告诉用户汽车无法启动,因为什么原因;如果合法,则开启发动机
  7. if(检查状态())
  8. m_发动机.启动();
  9. else
  10. throw "汽车使用了不配套的发动机!";
  11. }
  12. }

检查状态()这个该怎么实现呢?答案是必须有一个地方存储了汽车可以使用的发动机列表(当然也可以是发动机能匹配的汽车),我们可以实现一个字典,来保存 这个信息,然后根据这个字典来检查汽车状态。

这个字典的样子和下面差不多

Key                     Value

奥迪A6                  丰田发动机

凯梅瑞                  三菱发动机

。。。。。。            。。。。。。

4.10 在类的构造函数中实现语义约束时,把约束测试放到构造函数领域所允许的尽量深的包含层次中。

在构造函数中实现约束时,应该遵循这条原则,当然我还没想到如果没有遵循这条原则,构造函数会是什么样子?     在汽车类里怎么实现这个约束?

汽车类并不知道有奥迪A6或者凯梅瑞,这是继承的一个原则(派生类知道基类,但是基类不应该知道派生类),我能想到的实现方式就是如下

  1. class 汽车
  2. {
  3. 汽车(发动机 para)
  4. {
  5. if(!检查状态(para))//这个检查状态的实现和上面类似,从一个字典里查询
  6. throw new "发动机不匹配";
  7. }
  8. }

这种方式确实不会产生非法状态的汽车,但是对使用者来说很不友好。

4.11 约束所依赖的语义信息如果经常改变,那么最好放在一个集中式的第三方对象中。

4.9里的字典内容如果经常变化,那么最好存放到外部文件里,否则可以作为汽车类的静态属性来实现。

4.12 约束所依赖的语义信息如果很少改变,那么最好分布在约束所涉及的各个类中。

类包含的数据成员分为两种,一种是描述性的,如长宽高颜色等.

另一种是具有行为的子对象,如汽车包含方向盘,而方向盘本身就是一个具有"有意义的行为"的对象。

前者我们不去仔细讨论,只讨论后者。

4.9 类必须知道它包含什么,但是不能知道谁包含它。

如汽车必须知道包含了方向盘(否则汽车的左转,右转行为都无法实现),但是方向盘不能知道包含它的汽车,否则方向盘就无法重用到其它的汽车上。

4.10 同一个类包含的对象之间不应当有使用关系。

从复用性和复杂性角度考虑。

OOD沉思录 --- 类和对象的关系 --- 包含关系4的更多相关文章

  1. OOD沉思录 --- 类和对象的关系 --- 包含关系1

    4.5 如果类包含另一个类的对象,那么包含类应当向被包含的对象发送消息(调用方法).  也就是说,所有的包含关系都应当是使用关系. 如果不是这样,那么包含的类有什么用处呢?当然,面向过程的开发人员会想 ...

  2. OOD沉思录 --- 类和对象的关系 --- 包含关系3

    4.7 类包含的对象数目不应当超过开发者短期记忆数量,这个数目通常应该是6左右 4.8 让系统在窄而深的包含体系中垂直分布 假设有如下两份菜单: 正餐 --->甜瓜 --->牛排 ---& ...

  3. OOD沉思录 --- 类和对象的关系 --- 包含关系2

    4.6 尽量让类中定义的每个方法尽可能多地使用包含的对象(即数据成员) 这其实就是高内聚的翻版强调.如果每个类的情况并非如此,那很可能是这一个类表示了两个或更多的概念,记住一个类只应该表示一个概念. ...

  4. OOD沉思录 --- 类和对象的关系 --- 使用关系

    使用关系 对象A的方法MethodA使用了B的方法MethodB,则表示A对B存在使用关系 使用关系的最关键问题在于,A如何找到B,存在6种方案 方案一: A包含了B,B作为一个成员定义在A的类中,那 ...

  5. OOD沉思录 --- 类和对象的关系 --- 使用关系原则

    4.1 尽量减少类的协作的数量,即减少使用者和被使用者的数量. 协作意味着一定程度的耦合,但是完全没有协作的类也是没有意义的,最多只能作为一个库使用. 通过抽象,依赖接口,可以最大程度减少依赖的实现类 ...

  6. php课程 11-37 类和对象的关系是什么

    php课程 11-37 类和对象的关系是什么 一.总结 一句话总结:类生成对象,对象是类的实例化,一定是先有类,后有对象,一定是先有标准,再有个体. 1.oop的三大优势是什么? 重用性,灵活性.扩展 ...

  7. OC学习--类和对象的关系

    1. 如何创建对象 面向对象解决问题的时候必须有对象, 那应该如何创建对象? 以建造汽车为例子来解释: >建造汽车需要造车图纸, 图纸上 清楚的描述出 汽车具备的属性和功能(行为) >属性 ...

  8. Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员、局部),匿名对象的调用,构造代码块(5)

    Java面向对象(概述,构造函数,类与对象的关系,this关键字,成员.局部),匿名对象的帝爱用,构造代码块(5)

  9. 2.java面向对象类与类/类与对象之间关系详解

    继承.实现.依赖.关联.聚合.组合的联系与区别 下面的内容很基础,同时也很简单,但是也很重要. 继承 指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功 ...

随机推荐

  1. 移动端页面使用单位的问题:关于px、百分比、em、rem开发中逐渐转换的问题记录

    开始写前端页面也有了快两年时间,从一开始的懵逼到现在的淡定,但是不能改变我还是一只小菜鸟的事实,平时遇到的一些问题都会记录在文件夹里,现在都整理一下大家一起分享自己平时也翻翻看看~ 不知道大家平时写的 ...

  2. Android注解编程的第一步---模仿ButterKnife的ViewBinder机制

    ButterKnife的使用极大方便了Android程序员的开发,实际上,我们可以自己模仿一下实现. 首先就是要了解Java注解的使用. 我们首先要声明一个@interface,也就是注解类: @Ta ...

  3. 说说jsonp

    什么是jsonp jsonp充其量只能说是一种"方法".它可以让页面从其他域中获取资料.   首先要知道的是同源策略,在javascript中使用http请求(ajax)是会受到同 ...

  4. 关于Latch争用

    Latch是什么     Latch是SQL Server引擎保证内存中的结构的一致性的轻量同步机制.比如索引,数据页和内部结构(比如非叶级索引页).SQL Server使用Buffer Latch保 ...

  5. 如何转移数据库MDF和LDF文件

    我们可以很轻易地使用SQL Server来创建一个数据库,创建的数据库实例将存储在指定的默认位置(不一定是C盘,可以手动变更默认存储位置).假设此时数据库实例创建在了C盘中的默认位置,亦即是与数据库安 ...

  6. Oracle Fusion Applications (11.1.8) Media Pack and Oracle Application Development Framework 11g (11.1.1.7.2) for Microsoft Windows x64 (64-bit)

    Oracle Fusion Applications (11.1.8) Media Pack for Microsoft Windows x64 (64-bit) 重新搜索   常见问题    提示  ...

  7. 给文本框添加模糊搜索功能(“我记录”MVC框架下实现)

    步骤: 1.在文本框中输入内容时,触发keyup事件: 2.在keyup事件的处理方法中,通过Ajax调用控制器的方法: 3.在控制器方法中,搜索满足条件的数据,这里分页获取数据,且只取第一页的数据, ...

  8. Winform开发框架之字典管理模块的更新,附上最新2013年全国最新县及县以上行政区划代码sql脚本

    在很多项目里面,字典管理是必备的项目模块,而这个又是比较通用的功能,因此可以单独做成一个通用字典管理,例如这个模块,可以通过集成的方式,使用在我的<Winform开发框架>.<WCF ...

  9. 重新想象 Windows 8.1 Store Apps (86) - 系统 UI 的新特性: Theme, 窗口宽度大小可变, ApplicationView, DisplayInformation

    [源码下载] 重新想象 Windows 8.1 Store Apps (86) - 系统 UI 的新特性: Theme, 窗口宽度大小可变, ApplicationView, DisplayInfor ...

  10. android dp

    http://www.see-say.com/viewnews-47657.html http://cn.club.vmall.com/thread-970026-1-1.html http://ww ...