如何以面向对象的思想设计存在关联的实体类?

  针对前两天在本人公司引起同事激烈讨论的话题(如何以面向对象的思想设计存在关联的实体类),我设想了一个虚拟的应用场景,通过翻阅各种资料、请教各位同事以及结合我自己的一些经验,进行了简单的设计。这种设计是我自认为合理,并极力鼓吹加以应用的一种设计方法。欢迎各位高人猛烈抨击,不吝指教,指出设计缺陷,以求大家共同进步!

 

补充:

针对各位网友的评论,我把我当时遇到的问题也贴出来,让大家来议论一下,怎么做才是真正的面向对象。

我的问题疑问点:当两个实体类是“has”关系时,该如何设计这两个类?

1、班级类中有List<学生类>属性,学生类中有班级类属性;

2、班级类中有List<学生类>属性,学生类中没有任何关于班级的属性;

3、两个类中都没有任何对方的属性,它们的关系体现在业务类中;

4、班级类中没有List<学生类>属性,学生类中有标明班级的唯一标示的、类型是基本类型的属性

以上是我们形成的四种不同的观点,那哪一种是面向对象的呢?

我个人认为

第1种会造成嵌套;

第2种把List<学生类>当成一个属性,是否会使这个类变的庞大?如果不是班级,而是仓库和仓库里上万种的物料呢。岂不是List里有上万笔记录,在不需要的时候,不占内存吗?

第3种看起来好像很符合面向对象,但在处理诸如已知一个学生,然后得到他对应的班级中的全部学生时有点麻烦;

第4中就是我现在想出来的方法,但大家都说这个不符合面向对象,那到底应该怎么做呢?

  

 以下就是我目前想出来的方案:

假设需求:设计一个学生管理系统,实现如果发现某班级中的一位同学犯错误,则全班同学每个人都扣除一个小红花;

1、  设计实体类;如图:

 

2、  映射数据表;

3、  设计客户端

a)         由需求得知这里需要一个公开的惩罚方法:Punish(blunderStudent : Student)

b)         由需求得知实现惩罚方法的算法:

                                       i.              通过某个学生得到该学生所在的班级:GetClass(classId : Integer) : Class

                                     ii.              通过班级得到该班的全部学生: GetStudentList(classId : Integer) : List<Student>

                                    iii.              循环所有学生,扣除每个人一个小红花:SubFlower(blunderStudent : Student)

    

4、  设计业务类

a)         业务中有两个方法需要学生业务类去实现:GetClass(classId : Integer) : ClassSubFlower(blunderStudent : Student)

 

b)         业务中有一个方法需要班级业务类去实现:GetStudentList(classId : Integer) : List<Student>

5、  设计持久层接口

a)         学生业务类中的GetClass(classId : Integer) : Class方法需要通过持久层获取对象;SubFlower(blunderStudent : Student)方法需要通过持久层保存对象;

 

b)         班级业务类中的GetStudentList(classId : Integer) : List<Student>方法需要通过持久层获取对象列

 

6、  设计持久层

a)         分别实现持久层接口

 

7、  通过ORM工具实现持久层与数据表的关联

8、  根据不同的部署环境,选择设计Web UIWinForm UI,或其他用户界面

 

         附:整个类图

 

各位网友,根据你们提的意见,我对此设计做了一些改动,请大家继续讨论,这样是否就更贴近于面向对象的设计。

惩罚学生功能设计第二版:

我做了以下改动:

1、将减少小红花的行为,重新放回到学生实体类中。依据是:“自己的事情自己做”

2、删除原来客户端业务类中的不必要的私有方法,变成了只封装“惩罚学生”的公共方法的业务类

3、原来的StundetnController和ClassController类其实是服务类,故变成一个统一的服务类,这个服务类本质是提供持久层操作服务的,故设计了根据班级ID查找学生队列,以及保存学生最新状况的方法,而这个服务类是依赖于IDao接口的。

4、设计持久层接口,提供根据自身ID查找子类列以及更新对象的泛型方法;

5、设计持久层泛型类,处理实体类的CURD操作;

以下是新的类图,欢迎继续拍砖!

posted @ 2011-01-14 11:12  智会超  阅读(...)  评论(...编辑  收藏