面向对象设计之一 封装与共生性

来源:互联网 发布:阿里巴巴大数据 编辑:程序博客网 时间:2024/05/05 12:19

1 封装


       没有经过封装的原始代码规定为0级封装,而面向过程的子程序可以称为一级封装。而类则封装了众多的子程序,集合在一起形成一个高级别的封装,因此类是二级封装。组合类的包,则可以称为三级封装,而构件则可以看作更四级封装。


2 共生性


在两个元素A和B之间,共生性意味着:

1 如果在A中进行了一些变化,那么为了保持全面的正确性,同样需要对B进行改变,或者至少要仔细进行校验。

2 或者为了保持正确性,需要在A和B中同时进行一些变化


2.1 共生的性质


为了实现共生性,两个元素A和B之间不能相互通信

一些共生性的形式具有方向性,例如名称共生性,存在着单向的共生,也存在着双向的共生

一些形式的共生性是没有方向的,如果A和B之间没有显式的引用。如A和B使用的运算过程。


2.2 共生性的种类


类型共生

A:   int i;

B:   i=7

如果A处i声明为char,则B处自然需要变化

名称共生

上例中,如果A处声明变为j,则B处也需要进行变化。在派生类中如果使用了基类的某个名称,如果基类发生变化,则派生类也需要变化。

显式共生

像上面这两个例子,共生是显而易见的,通过阅读程序就可以快速找到。

隐式共生

然而,有时共生性的显现却并不是那么明显,需要花费大量的时间和精力去检测它,除非在显著的位置具有详细的文档说明。下面举一个隐式共生的例子,在古老的汇编语言中,我们经常可以看到的一种位置共生性。由于代码位置而存在的共生性。

A:  jump Y+38

B:  clear R1

…//38字节代码

clear R2

位置共生性

比如A和B的必须以一定顺序、必须相邻,比如形参与实参的对应。

常量共生

当在系统中使用一个常量来定义一个属性时,这个变量和常量便发生了共生

算法共生性

比如hash表中的插入和查找使用了相同的hash算法

上面的大部分共生性都是静态共生性,这些共生性是体现在静态的代码中。而动态共生性,则依赖于运行代码的执行模式或对象的交互模式。下面列出一些动态共生的类型。

执行共生性

执行共生性是位置共生性的动态表现形式。它有几种类型,包括顺序和相邻。

时间约束共生性

实现系统中经常出现,为了完成某个操作,而此操作必须在规定时限内完成。

数值共生性

存在一些约束,在数值之间存在着协变性。比如三角形的三条边的数值。

标识共生性

id共生性,两个指针指向同一个内存,当一个指针修改了内存的内容后,另一个指针指向的内容也发生了变化。

差异共生性

为了保证正确性,A和B必须保持不同,这称之为差异共生性。这种共生非常常,比如同一局部的多个变量不能重名。导入不同命名空间存在的命名冲突等都是共生性的体现。在多重继承下,多个基类中的同名操作也是同样的情况。


2.3 共生性和封装边界


封装是对共生性,特别是差异共生性的一种检验。如果系统没有任务封装,在大量代码中,如果改动一个地方,则你需要检查所有的代码以查看是否有共生性需要解决。一个没有封装单元的系统会存在两个问题:共生性泛滥和混淆真正的共生性。

面向对象方法至少可以驯服在传统模型系统中仅仅处于1级封装的不太好使用的共生性,即基于类的2级封装可以更容易限制共生的存在范围。

为了提高系统的可维护性,共生性提供了三个指导原则:

通过将系统拆分为封装的元素使得整个共生性达到最小化。

将任何超越封装边界的共生性最小化。

在封装边界范围内将共生性最大化

因此任何穿越了封装的边界而发生的共生说明这上封装将不合理,或者违反了面向对象的设计原则。

原创粉丝点击