首页 技术 正文
技术 2022年11月12日
0 收藏 646 点赞 4,839 浏览 1594 个字

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 同一个类包含的对象之间不应当有使用关系。

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,084
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,559
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,408
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,181
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,818
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,901