程序员的自我修养
Home » Java语言, 设计模式 » 一个简单的OO问题

一个简单的OO问题

0条评论1,489次浏览

问题

一个同事发来的题目:学校有三种人员,第一种为教师,属性包括名字、教工号、电话、地址;第二种为学生,属性包括名字、学号、电话、地址、平均成绩;第三种为辅工,属性包括名字、辅工号、电话、地址、工种。使用你学到的面向对象设计的方法,实现这三种人员的类表示,并实现三种人员的添加、修改、删除,可在内存进行增删改的操作,不需要永久保存。

注,可使用List保存人员,如没有使用OO设计方法,本期作业不通过,仅使用类不是OO设计。

答案v1

大致扫了一眼题目,是一个简单的OO设计问题。于是第一版答案很快出来了。

抽象父类Staff

子类Student,Teacher和Worker类类似,在此省去。静态set用于在内存中保存对象,为了防止出现new Student().getSet()这样丧心病狂的方法来获取整个数据集,添加了静态方法list(),这样可以通过Student.list()方法来获取整个数据集。

测试

运行结果

一切都正确的,可以CRUD。但是,为何看起来那么的别扭。没有满足OO设计吗?貌似很符合,好像还采用了模版方法的设计模式。那问题出在哪里?

看看测试代码中的这两句:

对象可以调用自己的方法来操作自己的CRUD,这是一个不太常见的设计方法。反正我没在哪里看到过其它人这么设计,我第一次这么设计是以前有个系统需要大量的在工作流中添加监听器,而监听器要进行CRUD操作的时候还要从SpringContext中获取相应的Service,显得十分繁琐。于是可以自己操作自己的CURD的类就这样设计出来了。但是,这样的类在某些特殊情况下确实好用,但对于传统的思维方式来说显得就十分的异类了。就好像上面的代码,一会自己操作自己的add()方法,一会又通过静态方法Student.list()来获取数据集,相近的功能分布在了两个不同的地方。我想这就是为何觉得别扭的原因。于是传统的Service、Dao操作CRUD方法的答案就出来了。

答案v2

接口IDao,这里多添加了几个方法,使得更像一个Dao了。

实现类Dao

抽象父类Staff,现在的Staff显得十分的简洁,功能也十分的单一。

子类Student,也变得简洁了些。

测试

运行结果

这样就感觉正常多了,通过Dao来操作每个子类的CRUD,功能解耦,而且还方便扩展,例如继续添加Staff的子类,如:校(qin)长(shou),除了添加子类以外不用做任何其它的改动。

继续改进

看到那该死的5个参数的构造函数了吗?为何该死?就是太长了,5个参数,每个参数什么意义一点也不明确。若构造时只需要id和name就可以构造的话就需要重新添加一个构造函数,只需要id、name和mobile也可以构造则又需要添加一个构造函数......抓狂吧?颤抖吧?怎么解决呢?建造者模式

继续以Student为例,现假设id和name为必须的属性,其它的属性可以设置也可以不设置。采用建造者模式后的代码如下。

这样创建Student对象时则可以显示的设置每个参数,如下。

和5个构造参数的构造函数比起来是不是有种高下立判的感觉。正如Effective Java中所说的,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是不错的选择。当然建造者模式相对Setter、Getter方式的类各有利弊,比如上述代码中就无法改变已创建好的Student对象的属性。

最后

不同的环境下,不同的设计方式有不同的效果,能选择最适合当前环境的即可。不必要纠结于其它的条条框框。比如那个自行CRUD的设计,怎么看都是个异类,但在项目里确实是最合适的。当然,需要这样的设计来弥补的项目我不想遇到第二次(该项目持续开发了8年,经过无数人的交接,技术大部分是8年前的技术,没错,还是国企自主研发项目,你懂的。。)。

(转载本站文章请注明作者和出处 程序员的自我修养 – SelfUp.cn ,请勿用于任何商业用途)
标签:, ,
发表评论


profile
  • 文章总数:78篇
  • 评论总数:252条
  • 分类总数:31个
  • 标签总数:43个
  • 运行时间:946天

大家好,欢迎来到selfup.cn。

这不是一个只谈技术的博客,这里记录我成长的点点滴滴,coding、riding and everthing!

最新评论
  • pacificLee: :twisted:
  • 小码: 为什么没有后面的呢,只有前10个
  • Anonymous: :lol:
  • Anonymous: :razz: 楼主是属于会聊天的。 我想问,sqoop发了几个版本了,应该没这些问题了吧。
  • Anonymous: Config.kafkaConfig.kafkaGroupI d 这个是指自己配置的group id 还是从 import org.apache.kafka.common.config .Config 这个类...
  • Anonymous: ZkUtils.getPartitionsForTopics (zkClient, Config.kafkaConfig.topic) 那个方法是在 spark-streaming_2.10 中 kafka...
  • Anonymous: ZkUtils.getPartitionsForTopics (zkClient, Config.kafkaConfig.topic) 你确定 kafka 里面有这个类 ? 个人在kafka 最新 稳定版...
  • Anonymous: :roll:
  • Anonymous: 很不错,试问有java版的吗?
  • Anonymous: 赞
  • Anonymous: 哈哈 看楼主的吐槽乐死了 where子句是可以写的 同样找不到资料 一点点试出来的 select id from xxxx where ${CONDITIONS} and 1=1 and 2=2 limit 4
  • EVIL: 我在运行完C4.5的代码后,显示 defined object DecisionTreeTest 是什么意思?这是有错误吗?运行结果在哪里看?
  • sf: 楼主的问题,我都遇到。。。没办法项目已经定型了,最后都硬着头 皮一个一个的改了源码
  • zz: 我去,楼主你真及时,我们今天上了新的HTTP2 push之后也发现速度曲线很奇怪,开始有200k/min,跟 另一台老的推送协议速度差不多,但是过了一会,立马降到只有几k /min,百思不得其解,我们还用了一个海外代理,在...
  • qi365: :mad: 很可恶,百度助纣为虐~
  • qi365: :? :shock: haha~ very good~
  • 张是大: 《深入浅出Spark机器学习实战(用户行为分析)》 课程网盘下载:http://pan.baidu.com/s/ 1mixvUli 密码:1pfn
  • Anonymous: :???:
  • Anonymous: 我用着sqoop感觉还可以,select 几十个字段也没事,估计是版本低。。
  • Anonymous: :grin: