对进入面向对象世界的思考

练习题
刚开始学习有关UML和面向对象中的设计原则,于是找了一道题来试一试

最开始我们设计的类图是如下所示:

带来的问题
然而对上面的 Button/Dialer 类,会有几个问题如僵硬、脆弱、不可移植
僵硬
增加一种 Button 类型,就需要对 Button 类进行修改;
修改 Dialer,可能回影响 Button
脆弱
当想修改 Send 按钮功能时,有可能不小心破坏数字按钮;
当这种函数很多时,很可能会漏掉某个函数,或其中的某个条件分支。
不可移植
设想我们要设计密码锁的按钮,它只需要数字按钮,但 Button 的设计使它必须“附带”一个“send”类型的按钮
改进方法一:
对于以上的问题它不满足开闭原则,因此需要对齐进行改进
第一种改进方法,使用继承的方式

因为我又不甘只看图,所以也顺手写了一下代码,具体代码如下:
Button类:
DigitButton类:
SendButton类:
Dialer类:
改进方法二:
改进方法二使用策略模式:

自己也是第一次看着UML来写代码,第一次的我写成了这个样子,不怕大家笑话我就直接上图了。

刚写完我就马上意识到了自己写的有些问题
从图里可以看到 Button 类根本没有 跟 ButtonServer 之间产生依赖关系,也就是上图中虚线的箭头
对于第二个向上指向的箭头,应该是继承的关系,我默认 ButtonServer 是一个类了,但如果要符合依赖导致原则,高层模块依赖接口而不应该依赖实现,所以 ButtonServer 应该是一个接口,然后 Dailer 类实现 ButtonServer
已经意识到这写的啥也不是,根本不是一个策略模式,于是又重新看了策略模式的类图 如下图所示

然后进行了第二次修改
Button类:
ButtonServer类:
Dialer类:
Main:
改进方法三:
改进方法三:适配器模式

来继续分享一下自己第一次照图写出代码的图,跟上一个一样,大概就看到了有几个类,类里面的方法

说一下上面的问题
Button跟ButtonServer应该是依赖关系,在我的第一个类里面什么都没有,没有之间的调用关系这里的问题最严重
然后还是 Button 其实这里应该是 策略模式,我这里些的啥也不是,这里只有适配器写对了
然后我们看正确答案
Button 类调用 ButtonServer
ButtonServer 类
DigitButtonDialerAdapter类
SendButtonDialerAdapter类
Main方法
改进方法四:
方法四:观察者模式

Button类
ButtonListener类
Dialer类
Phone类
总结:在这次Demo的练习当中感觉自己已经踏入了面向对象编程的世界,已经体会到了面向对象带来的红利,利用多态的特性来帮助我们实现真正的敏捷开发,最后感谢李智慧老师给予的指导,谢谢老师。
版权声明: 本文为 InfoQ 作者【云飞】的原创文章。
原文链接:【http://xie.infoq.cn/article/d7ac62b69ae09b95adaf54566】。文章转载请联系作者。
评论 (1 条评论)