美文网首页面向对象的分析与设计 OODA
第01章 - 良好应用程序的基石 - 《深入浅出面向对象分析与设

第01章 - 良好应用程序的基石 - 《深入浅出面向对象分析与设

作者: 勤劳的悄悄 | 来源:发表于2016-10-19 23:59 被阅读85次

    本章从一个吉他库存小程序开始,逐步改进,介绍了一些面向对象设计的核心思想。

    初始场景

    故事是这样开始的。。。。。。

    有个老板是卖吉他的,它想要一个程序能管理和搜索他的吉他库存。

    吉他店老板

    设计公司很快给出了最初的设计方案,有两个类:

    • 吉他类:存储每一把吉他的特征
    • 库存类:管理吉他库存
    吉他类 库存类

    此外,还给出了这两个类的具体代码实现。但是某些代码似乎有点“坏味道”,特别是库存类中的 search 方法,非常长、非常复杂。

    search 方法

    在模拟测试中,程序竟然没有按照预期工作:一把吉他明明存在,但是在库存中却查找不到

    测试出现问题

    软件开发的终极问题

    到目前为止,这个程序肯定是有问题的。

    这时候,三个程序员出场了,他们对如何修改这个程序提出了各自的看法,似乎都有道理。

    三人讨论

    他们三个人的讨论引出了终极问题:

    • 什么是伟大的软件
    • 怎么设计出伟大的软件
    终极问题

    伟大软件满足两个标准:

    • 符合用户的要求
    • 可维护、可重用、可扩展

    设计伟大软件有三个步骤:

    1. 首先满足用户的功能要求
    2. 引用 OO 原则
    3. 进行良好的设计

    修正错误并改进

    为了满足用户功能要求(伟大软件的第一步),要先修正原先程序中存在的错误,让程序首先能跑起来。

    错误找到了,是字符串字面量大小写引起的

    出错的地方

    对于如何修正这个错误,三个程序员又进行了讨论,他们认为在修正错误的同时,可以进行小的设计改进

    讨论

    下面是三个改进的地方:

    • 改进之一:用枚举常量替代字符串字面量来表示吉他的特征,这样可以避免拼写错误问题
    • 改进之二:对于那些只能用字符串的特征,搜索的时候先将它们都转换成小写,然后再比较
    • 改进三:原先的搜索功能只能返回第一个符合特征条件的吉他,现在可以将所有符合条件的吉他都返回

    当然,每一次修改完都应该进行测试,这次测试实现了预期目标。

    测试

    这一小节的核心思想是:软件开发一开始专注于实现功能,完成功能前不用太过在意设计问题。有点小的设计也无妨,但是实现功能是前期的重点

    单一责任原则和封装

    到目前为止,程序已经跑起来了,而且实现了预期的功能,但是仍然有一些地方似乎有问题。

    如果要搜索具有某些特征的吉他,需要先用这些特征创建一个吉他对象,然后传给库存类的 search 方法进行查找。

    问题是:一个完整的吉他对象有序列号和价格这两个属性。而搜索时创建的吉他对象并不需要这两个属性

    搜索吉他

    为什么会这样?对于这个问题的分析引出了一个重要的原则:单一责任原则!

    三个程序员进一步讨论,认为吉他对象承担了太多的责任,应该将特征部分放到另外一个对象中去

    Paste_Image.png

    他们新创建了一个规格类,将吉他的特征部分放到这个类中

    规格类

    这里还隐藏了一个原因:规格特征很容易发生变化,因此应该将他隔离出来,后面将会看到。

    现在给库存类的 search 方法需要传送一个规格对象,而不是吉他对象,不再有多于的参数了!此外,比较的时候也是用规格对象,而不是吉他对象。

    修改搜索方法

    再次测试目前为止的代码,一切正常。

    这一小节先引出了单一责任原则,最后告诉你用封装隔离变化,这些变化可能包括信息或者行为

    复用

    目前的代码已经不错了,但是它是不可复用的。

    现在老板想增加一个“琴弦数目”的特征,对于目前这几个类,会造成什么影响呢?

    增加属性

    影响如下:

    • 规格类:需要增加“琴弦数目”属性,并增加相应的存取方法。(规格类的改动不算太大)
    • 吉他类:吉他类的构造函数会接收一系列特征值,因此要增加一个参数以接收“琴弦数”;此外吉他类还需要创建规格对象,也需要增加这个参数。(吉他类的责任太多,创建规格类不应该是他的责任。同时他对规格类了解的太多。)
    • 库存类:库存类 addGuitar 方法接收一系列特征值作为参数,因此也需要修改;此外,search 方法比较吉他的特征,要考虑新增加的属性。(库存类也是对规格类的细节了解的太多)

    牵一发而动全身,说明代码的组织有问题

    很难复用

    这一节的最后又引出了另外一个概念:委托。

    委托最根本的目的就是划分责任,让每个对象只做自己该做的事情

    重构代码

    第一步:增加新的属性

    增加新属性

    第二步修改:给吉他对象注入规格对象,而不是在吉他对象内部创建规格对象,解除强依赖

    解耦

    第三步:将库存类 search 方法中的比对特征工作移动到规格类中,进一步解耦

    解耦

    最后再次测试,一切正常,得到一个设计良好的程序。


    总结:开发设计三部曲

    1. 快速实现功能
    2. 用 OO 原则进行封装
    3. 重构、解耦

    相关文章

      网友评论

        本文标题:第01章 - 良好应用程序的基石 - 《深入浅出面向对象分析与设

        本文链接:https://www.haomeiwen.com/subject/bmoxuttx.html