下面呢我们看这个其中这 就其中的几点,我们这个重点给大家 这个讲述一下。
第一点呢就是在问题域部分的设计的时候,一定要有这个复用的这个 视角,或者说这个要考虑复用啊。
复用呢有 两个方面,一个是如何向上复用,一个是为以后的这个系统
啊这个近似的系统提供一个复用的这个支持 这个比如说我们这个
如何尽可能的把在设计的时候就应该尽可能的,这个复用已经存在的一些模型资产
比如说现在呢我们这个在问题域部分分析的时候,拿过来 之后就要进行将问题域部分分析,变成问题域部分设计的模型的时候呢
我们这个有一个车辆的这么一个类,这个问题域部分的类 这个但是呢,我们这个通过寻找我们的这个资产,我们发现
模型资产我们发现,我们已经的已经存在的一个这个 类,它叫车辆。
这个车辆呢实际上已经是 被实现。
就是有一个专门的这个 编程语言中的类来支持这个,这个已经
把它封装到一个编程语言中的一个类里边去了,所以我们可以复用
那么如何我们在设计方案中体现这个问题呢,是吧?我们就实际上呢可以 这个将二者呢建立一些什么呢?
一种这个 泛化关系,但是建立泛化关系的时候要注意,就是说
实际上这个如果你这个找到了这个类,然后它
的这里边的所有的特征,正好是我这个现在问题域部分
类中的这个特征的一个子集啊,那就是非常好,是吧?就说它这个 我直接继承过来就可以了。
但是有些情况下呢,往往它们之间是一个交集的关系 是吧?可复用的类不是很正好,就说它跟我这个
问题域中的类有一些相似的特征,相同特征,也有一些不同特征 这时候对于它这个不同的特征怎么处理,这是一个非常关键的 问题。
有同学可能会说,这样不管它,它 对于这个可复用的类,这个有一些与我们复用问题域中的类,不同的这个
这些特征,我是就不管它。
拿过来我就这个,直接这个继承过来之后,我到时候不用就可以了
但是这时候,这个一般来说,我们很少会这样弄的
因为这时候呢会出现一些问题,一方面呢就是说
它可能和我们这个这种面向对象呢非常这个贴近于自然这个思维方式啊,有一些
背离,但是更重要的是在设计的时候呢
就说你可能知道你这个车辆,就不用它那个什么可复用类这种厂商,但是你
因为你这个设计的这个车辆很可能还要被其他的人所 复用,其他人在复用的时候可能就不知道这个问题,他就会误用
你这个继承的这个可复用类的这个问题 这一些不需要的一些特征会造成一些错误,我们后面还有一些例子来说明这个问题
所谓在这种情况下呢,那就分两种情况,一方面这个可复用
的类,如果说是你可以修改它的源代码的话,那么你可以直接就是
像我们这个设计中这个方法就是,你可以直接把这个一些它
不用的一些属性啊,一些操作给它删掉,或者说给它注释掉 这是一种方式啊。
另外呢就是说如果说你 不能修改它的源代码,并且人家的这个源代码呢这个还有为
其它的一些这个系统提供一些服务是吧?你这个修改的话会造成 人别的这个类这个功能上的损失,这时候呢
有一些方案啊,这个我们后面再讲。
所以这里呢我们是 就说给出了一个很,也是很容易理解的一个方案,就说这个直接
就给它复用过来,然后呢这个最简单情况下我可以修改它,修改它的一些源代码,我把它的
一些我现在不用的一些特征,我都给它划掉,完了意味着 我以后编程序的时候,我就需要修改它的复类,我就给它这个注释或者是删除
同时呢,我要把我这个本身我这个问题域中的类中的一些,符合了这个可复用类中的一些
特征,给它也在我这儿删除,这个删除不真的删除,因为我这个继承关系就说我这个
既然我是它的子类了,然后它就可以这个复用啊
这个我这个无条件的继承这些所有特征,所以它的所有特征 做上移,这是一个方案。
还有一个方案呢 我们看一下这个如何这个更好的向下复用 如何这个更好的向下复用。
比如说这是一个问题域部分分析的一个模型片段 这是一个发票项之间的各种关联关系啊,是吧?一个发票有多个发票项
然后一个客户呢可以开多个发票,是吧? 但是呢这个现在由于电子商务啊这个发展,是吧?现在有一些这个电子发票
比如说很多的一些电商,然后它们也就可以,开发票的时候呢不一定给你开发纸质发票了
给你开个电子发票,这个也就是这个电子发票就是我们称之为可发送发票,可以很 容易的进行这个通过平台啊或者说是通过
email 啊 进行传送这种发票啊,也可以用来
进行这个报销啊各方面的一个依据 这个就是电子发票,可以说认为是可发送发票啊
那这个本身作为问题域部分的分析的这个情况来说呢,应该说是一个
没问题啊,这个非常忠实的反映了当前的这个业务
但是我如果是拿这个模型片段作为我们问题域部分的设计啊,这时候呢
它就需要进行一定的调整,为什么进行调整呢?就是你要 考虑的比较这个全面一些,就说
尽管现在是一个发票的这么一种情况,但是呢 我们考虑是不是其它的一些电子政务、 电子商务中的
一些文档、 文件是不是也有这种可发送的功能?
你像什么合同,是吧?一些这个文件、 一些
政府的一些这个文件,它都可以做成电子的 这时候呢,如何这个向下的提供这个复用的支持就变得非常
重要了,是吧?这时候呢我们往往为了往下复用的时候呢,我们这样 就是新增一个可复用的、
可发送的一个文档,可发送的文档呢这个 实际上呢,这个文档呢可以指的是很多的这种情况,既可以是
这个发票也可以是文件,也可以是合同。
然后可发送的发票和发票之间构成一种什么呢?一种这个 多重继承关系。
这样的话呢它 可发送的发票一方面继承了这个发票的一些特征,一方面 继承了这个可发送文档的一些特征。
可发送文档也就说可以产生 电子版,可以这个邮寄呀,可以这个其它的一些传真呀,这 么一种情况啊。
而发票呢它是自己特有的一些特征,然后这两个继承过来之后呢实际上就
可以这个直接就可以这个作为我们 电子发票的一个类,但是我们这个有什么好处呢?就是
如果我们在这个系统中或类似的系统中啊,有一些什么不仅是发票,我这个
合同是吧?合同也可以电子的可发送的,那怎么办呢?直接用合同和这个可发送文档之间- 构成一个 这个多重泛化关系就可以了。
这样的话呢就是,实际上呢这个 可以很好地这个复用。
为什么这个 OOA 的时候不利于复用呢,就是它这个可发送发票呢
实际上呢它,它是一个我们叫这个 符合角色类。
符合角色类呢在分析的时候是允许的,在设计的时候我们一般来说 这个要尽可能的把它消除。
就是我们现实世界中的人啊、 各种事物啊都是 多重角色,但是这种多重角色不利于复用。
我们在这个设计的时候,要把这种多重角色类 拆分为多个类,这样的话呢就可以复用起来非常方便,是吧?有时候通过多重继承或者组合-
这种方式 给它,把这个多个角色组合成一个新的类,这样的话呢就比较灵活
还有一个在设计的时候要考虑的问题,就是对相似操作的处理,也是一个
比较繁琐的一个问题,是吧?就是有些时候这个 我们这个现在问题域中的类和这个需要复用的类
中,有些操作呢就是非常相似,但是呢又不是
完全相同,它的特征标记很相似,但是呢这个又不是完全相同,这时候怎么办?
是吧?在处理这方面的一些问题的时候呢,实际上呢这个
也是根据不同啊,它这个当前的这个场合的不同呢,有不同的处理
这个有些时候,我们这个可以改的时候可以适当的修改,如果不能改的时候我们这时候呢 有不同的处理方案这样。
这个比如说我们这个举一个例子,三角形和四边形都有 draw 方法,但这个 draw
方法呢 三角形是三个顶点,四边形四个顶点,是吧?它们这个多了一个参数啊,四边形比三角形多了-
一个参数 我为了这个统一二者的这个
操作,这个时候我怎么办呢,是吧?我在图形上呢可以加上一个 就是这个 draw 方法。
这样的话呢这个,它就四个顶点。
然后这个三角形的时候 这个顶点呢可以把这个最后一个顶点给它置为负数,或 0。
这样的话呢 就可以这个,它一旦这个
看到这个是个负数的话,它就把它用了一个按三角形进行处理就可以了
这是一种方案,这样的话呢就是把它们统一成 了一个相同的接口,这样的话便于这个实现接口复用,或者说是多态
还有一种情况呢就是,这个比如说这个猫和这个鸭嘴兽。
它们的这个 都有这个生孩子这么一种这个操作。
但是这个操作 实际上呢是它的特征标记,或者说这个 它的这个 signature
它是完全相同的 但是呢它们之间呢,这个实现这个操作的这些方式是不同的,是吧?猫啊是胎生
鸭嘴兽呢是卵生,这个 生孩子这个过程描述,这个方法这个东西是不同的
这就是为什么无法把它们统一到一块儿呢,那就是
用典型的我们的这个啊,这个建立一个复类,这个复类呢哺乳动物,哺乳动物呢一个 childbearing。
这样的话呢就给它们 这个统一了它们的什么呢?接口。
统一接口之后呢我们这个 利用这个面向对象中的这种多态,这样的话呢就可以 实现它们的接口复用。
这样的话呢,一堆鸭嘴兽的这么一个 堆,或者说一个队列,一堆哺乳动物的队列,不管它是猫啊、
狗啊 还是鸭嘴兽,然后呢都可以调用我这个 childbearing
这个相同的这个接口啊,这样的话就不用一个 条件判断,这样的话呢这个但是呢,它在
iii 的时候却会根据你这个不同的类型,来调用这个相应的 类型的一些这个方法。
这就是这个多态,这也是在设计的时候也是需要考虑的一个问题
另外呢就是有些情况下我们前面提到,我们需要复用一个 可复用的类中的某些方法,但是有些方法呢是我们不想复用的
就说它这个复类呀,它的这个特征可能要比我子类
这个用到的这些特征呢要多,有些特征呢它是,我们是想 把它去掉的。
但是我们又拿不到这个源代码,或者说我们即使 拿到源代码我们也不能有这个权限,那怎么办呢,是吧?
这里给出一种方案就说像这个鸟,鸟有飞的一个操作,一般来说,按照常识来说这个鸟啊
它都是飞的,都是可以这个有个飞行的这么一个操作 啊但是呢,这时候我们这个用特殊的鸟,这个企鹅。
这个企鹅呢它是不能飞的 不能飞的话呢,这时候你无法把它删除掉,是吧?
因为你继承了这个其它的一些特征都非常好,是吧? 有羽毛啊,是吧?有这个各种这个
鸟的一些特征,然后这个但是它唯一的一个特征就是它 不能飞,但是你也不能给它删除了怎么办呢?这时候呢你要重写
这时候你要重写这个企鹅的 fly 的这么一个操作啊,让它呢
这个显示一个提示啊提示,就是一旦那个用户
这个不知道这种情况下呢,调用了这个让企鹅飞的这个操作,这个企鹅
就会给他反馈一个不能飞的这么一个提示,或者说一个出错
这样的话呢,这个就可以解决这个问题了。
通过这种方式呢 就可以也是一种这个渠道,也是就是可以重载它的
通过这个重载复类的一些不用的方法,然后给它
重写复类的不用的方法,这样的话呢可以这个,并且重写过来之后呢
给它进行提示,而不会执行复类的一些实际的工作。
啊,这样的话也是一种办法