对象建模笔记--角色建模1面向对象技术其实是一种以现实世界的自然观点看待软件代码的方法。原先的软件的编程方式是过程式的,但是这种过程式的编程方式没有办法处理过多的代码行,因为人的思考能力是有限的,很少有人同一时刻看的代码能够超过500行以上的,当然,有特异功能者除外。人们发明了非常多的方法来使过程式编程方法更加的方便,其基本的思路都是通过一些技术,对大段的代码行进行分割,例如代码块、函数、模块、工程、静态联编、动态联编等等。但是直到面向对象技术出现之前,并没有出项完整、彻底的解决方案。 我们刚开始学习面向对象的时候,总是要了解上一堆狗啊,哺乳动物啊之类的关系,其实这些都是为了向我们展示面向对象是符合人类对世界的认识的,也就是符合人类的世界观的。但是糟糕的是,面向对象技术看起来似乎应该是符合人们的世界观的,但是好像却要比过程式编程技术要难的多。好吧,我们撰写此文的目的就是为了解决这个似是而非的问题,揭开面向对象的面纱。你会发现,面向对象其实就是这么自然。 我们所有讨论的例子都集中在企业应用中,一方面的原因是企业应用其实是人类社会的一个缩影,能够灵活的运用面向对象技术来分析企业应用,那应该说你已经到了老鸟的级别了。另一个方面则是因为个人的原因,本人并没有接触过其它性质的系统,所以这也是没有办法的事情。 首先我们要谈的是对象所扮演的角色的问题。我们说狗是对象扮演的角色,文具也是对象扮演的角色。对象能够模拟出现实世界中各种各样的概念、事物、事件…。我们把扮演特定角色的对象称为对象角色(object role)。现在我们先抛出第一个问题,一个公司中拥有各种各样不同的雇员,包括工程师(engineers)、销售员(salesmen)、主管(directors)、会计(accountants)。我们如何把这些现实世界中的概念(或者说是事物,这取决于你如何看待这些名词,以及你的需求)对应到面向对象中?或者说,我们如何用对象来表示这些概念?类似的问题还有很多,但我们这里就不多说了。值得注意的是,我们这里提到的对象可以理解为类,其实还包括类型,不过在有些语言中类型也被当作类来处理,而类的具体实例,我们会称之为对象实例。 第一种处理方法,也是最简单的处理方法――使用单个对象来表示统一的概念。这是下文中所有方法的基础,因此不要小看它。这是什么意思呢?也就是说,不论你要处理的概念是工程师,还是主管,或是会计。我都用
来表示它们。那么我应该如何分辨员工是工程师,还是会计呢。好,最简单的方法是使用一个string来表示员工职业的分别:
当然,其它的类型信息也是允许的:
这里的JobDescription是另一个用于描述职位信息的类。是不是非常的简单?这只是一个开始。但是要注意,根据我的经验,越是简单的处理方式其实越是实用。对没有太大差别的概念使用统一的对象来表示它们,并使用字段来表示概念的区别,对于大部分的需求都已经足够了。而困挠我们迟迟不敢做出简单的决策的原因往往是对未来变化的恐惧,也许你认为在未来用户可能会修改他们的需求,要求加入新的业务逻辑,处理不同的职位。例如,工资的算法依赖于不同的职位。对未知事物的恐惧往往导致我们进行过分的设计。放轻松些,变化并没有什么了不起的,就像下文提到的,只要接口设计足够的稳定,变化不足畏惧,适应变化正是面向对象所擅长的。因此,记住这一点,永远只是处理当前的需求,不要进行过分设计。这也是敏捷方法所提倡的。 好吧,这时候我们需求开始发生变化了。工程师、主管、销售员以及会计这些员工之间出现了非常大的差异。因此我们尝试使用另一种方法:每个单独的概念对应到一个独立的对象上。这样,我们就有了工程师对象、主管对象、销售员对象、会计对象。为简便起见,这里的代码我就不写了,和前一个方法的代码非常的类似,只是代码的量变大了而已。相信很多程序员对这种处理方法都不陌生。这种方法的好处是它能够把不同类型员工给分开,并使得基于不同职业进行业务逻辑处理成为可能,而且不会导致对象间耦合度的上升。 有利就必有弊。这种方法有两个致命的缺点:第一种是重复代码的产生,我们注意到,不论是工程师,还是主管,他们都属于员工,因此他们都有姓名、性别、年龄、住址等相同的个人信息。由于使用的不同的对象来建模它们,这些属性不得不重复好多遍。就算我们有这个耐心把这些属性一一放到各个对象中,但噩梦仍然没有结束,如果我们那需要增加一些属性,而这些属性恰巧是属于各个对象所共有的。那么我们不得不在各个对象中依次加入这些属性。天哪,总有一天我会疯掉的。什么,继承?你说对了,这就是我们要使用继承机制的一大原因。关于这一点,我们在下文讨论。 现在我们来看第二个缺点。完整性不足。举一个例子,如果有一位员工,他既是工程师,又是主管。如何处理这种情况?我们只好为这个人建立两个对象,但是我们就没有办法分辨出它们其实表示的是同一个人。如果工程师和主管之间存在依赖关系的话,那可就糟糕了。这种问题在企业应用中时有发生,最经典的例子是供应商和客户同属于一个客户的情况。在http://www.erptao.org上有一篇文章就是专门讨论对这种情况的解决方法的。大家可以参考。 总的来说,这种方法不算是一种好的处理思路,能不用就不用吧。不过仍然是要具体情况具体分析。 当当当当!继承机制进场!我们回到第一个问题结束时留下的疑问,现在我们希望充分利用面向对象的三大特性之一的继承来解决我们遇到的问题。好,我们首先定义一个员工对象(或是其它什么名字),这个对象定义了员工的公用属性以及公用逻辑。然后我们再让工程师对象继承自员工对象,在工程师对象中实现工程师特有的属性和逻辑。好,依法炮制,我们得到了一个父对象-员工,以及三个子对象。如果我们需要处理的层次仍然停留在员工层次上,我们只需要处理员工对象,如果我们需要处理特定的员工,那我们就单独处理员工对象的子对象。如果我们有一位员工既是工程师,有时主管,那我们就也可以创建相应的子对象,如果我们希望增加退休员工的概念,我们也可以再加一个子对象。如果...等等,还如果呢,出问题了。只要是有面向对象编程经验的程序员都知道单根继承和多重继承的区别,而现在的很多语言都是不支持多重继承的。那么,我如果要在不支持多重继承的语言中处理员工既是工程师又是主管的例子,我就需要创建一个工程师/主管的子对象,那么不用多少时间,我们手上的子对象的数量就会急剧上升。这就是典型的子类爆炸的情形。此外,继承的机制一般都是静态的,而不是动态的,也就是说,我不能够在运行时随便改变对象的类型(注意,和多态的概念不同)。 上一篇:使用reiserfs格式安装RH8 下一篇:对象建模笔记--角色建模2 更多相关文章
|
推荐文章
精彩文章
|