Head.First.Object-Oriented.Design.and.Analysis《深入浅出面向对象的分析与设计》读书笔记(四)...

 

  

 

  

 用真实世界检验你的软件-分析

 

 引用

     

      是时候毕业了,时候去真实世界检验自己的软件了。

     

      上个版本的狗门很是成功,卖的很疯狂。但是越是卖的还要,抱怨就会越多。下面就是一个用户的意见。

      “我非常喜欢你的系统,那个语音识别器。但是在我安装了之后,每次邻居家的狗叫的话,门也会自动打开。但是这不是我想要的效果。”

 正文

     

      你的软件有了一个上下文。到目前为止,我们是在一个真空,没有结合软件运行环境的情况下开发软件。换句话说,我们把软件想象为:运行在完美的世界,在我们预期的情况下运行。每个人都很轻松,周围没有很多条狗。

      但是我们的软件终究要运行在真实的世界,而不是一个完美的世界。在真实的世界中,可能会运行错误。周围也会有很多的狗,猫之类的动物。

      使得你的软件在真实世界不被搞糟的关键在于分析:在你把软件放到真实世界之前,找出潜在的问题,并且解决这些问题。

      1、确定(识别)问题

      第一步是找到潜在的问题。我们已经知道,就是邻居家有很多只狗。

      使用遥控器没有问题,因为是人工干预。人是可以识别自己家的狗叫的。但是语音识别器好像就差了点,它一听到狗叫就会打开门。意味着,任何一只狗叫都可以打开门。

      2、设计一个解决方案

      使我们的use case出了问题,在识别器听到狗叫之后没有识别是否是自己家的狗,就打开了门。应该在听到声音之后,需要if判断一下,然后再打开门。

      还需要识别器有存储主人家的狗叫声,才可以在收到狗叫之后进行比较。这时候,你就会发现,需要添加一个use case,就是存储狗叫。用例比较简单,就是:

      1)主人家的狗叫

      2)识别器存储主人家的狗叫声

      用例增加之后,就需要我们修改代码。修改的方式有很多种,先看第一种:

      在DogDoor中添加一个string类型的字段,用来存储叫声;添加一个方法来设置叫声;添加方法来获取叫声。

 

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  BeautyCode.Common.ConApp.Head.First.OO.Design
{
    
public   class  DogDoor
    {
        
private   bool  _open;
        
private   string  _allowBark;
        
public   void  SetAllowBark( string  bark)
        {
            _allowBark 
=  bark;
        }
        
public   string  GetAllowBark()
        {
            
return  _allowBark;
        }
        
public  DogDoor()
        {
            _open 
=   false ;
        }
        
public   void  Open()
        {
            Console.WriteLine(
" the dog door opens " );
            
this ._open  =   true ;

            System.Threading.Thread.Sleep(
5000 );
            Close();
        }
        
public   void  Close()
        {
            Console.WriteLine(
" the dog door closes " );
            
this ._open  =   false ;
        }
        
public   bool  IsOpen()
        {
            
return  _open;
        }
    }
}

 

      另外一种做法就是比较面向对象的程序员写的,新建一个类,定义叫声类

 

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  BeautyCode.Common.ConApp.Head.First.OO.Design
{
    
public   class  Bark
    {
        
private   string  _sound;
        
public  Bark( string  sound)
        {
            _sound 
=  sound;
        }
        
public   string  GetSound()
        {
            
return  _sound;
        }
        
public   override   bool  Equals( object  obj)
        {
            
if  (obj  is  Bark)
            {
                Bark bark 
=  obj  as  Bark;
                
if  (bark._sound.Equals( this ._sound))
                    
return   true ;
                
else
                    
return   false ;
            }
            
return   false ;
        }
    }
}

 

 

 

      DogDoor类中的叫声字段的类型则变成了新建的Bark类

 

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  BeautyCode.Common.ConApp.Head.First.OO.Design
{
     
public   class  DogDoor2
    {
        
private   bool  _open;
        
private  Bark _allowBark;
        
public   void  SetAllowBark(Bark bark)
        {
            _allowBark 
=  bark;
        }
        
public  Bark GetAllowBark()
        {
            
return  _allowBark;
        }
        
public  DogDoor2()
        {
            _open 
=   false ;
        }
        
public   void  Open()
        {
            Console.WriteLine(
" the dog door opens " );
            
this ._open  =   true ;

            System.Threading.Thread.Sleep(
5000 );
            Close();
        }
        
public   void  Close()
        {
            Console.WriteLine(
" the dog door closes " );
            
this ._open  =   false ;
        }
        
public   bool  IsOpen()
        {
            
return  _open;
        }
    }
}

 

      相应的识别器类中的代码就应该修改为

      识别器1

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->    public   void  Recognize( string  bark)
        {
            Console.WriteLine(
" Bark Recognizer: heard a  " + bark );
            
if  (_door.GetAllowBark().Equals(bark))

                _door.Open();
            
else
                Console.WriteLine(
" this dog is not allow " );
        }

 

 

 

      识别器2

 

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> -->   public   void  Recognize(Bark  bark)
        {
            Console.WriteLine(
" Bark Recognizer: heard a  "   +  bark);
            
if  (_door2.GetAllowBark().Equals(bark))

                _door.Open();
            
else
                Console.WriteLine(
" this dog is not allow " );
        }

 

 

      识别器2明显好于识别器1,因为在2中将声音比较的任务委托给了bark类来处理,识别器本身不处理,只是根据处理的结果来做出决定。这样就松散了耦合,解耦了识别器类和叫声类。因为其他叫声也很容可以添加进来,否则每一种叫声都必须配备专用的识别器了。

      在分析的时候,需要注意需求或者是用例中的名词和动词。名称经常会需要转换成类,或者是类的一个属性。动词则经常会是一个方法。

      继续上面的分析。

      狗一般不是叫一声,有可能要叫很多声,只要一个声音匹配成功,就应该打开门。识别器需要存储多个狗叫声。

     

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  BeautyCode.Common.ConApp.Head.First.OO.Design
{
    
public   class  DogDoor3
    {
        
private   bool  _open;
        
private  List < Bark >  _allowBark;
        
public   void  SetAllowBark(Bark bark)
        {
            _allowBark.Add( bark);
        }
        
public  List < Bark >  GetAllowBark()
        {
            
return  _allowBark;
        }
        
public  DogDoor3()
        {
            _open 
=   false ;
        }
        
public   void  Open()
        {
            Console.WriteLine(
" the dog door opens " );
            
this ._open  =   true ;

            System.Threading.Thread.Sleep(
5000 );
            Close();
        }
        
public   void  Close()
        {
            Console.WriteLine(
" the dog door closes " );
            
this ._open  =   false ;
        }
        
public   bool  IsOpen()
        {
            
return  _open;
        }
    }
}

 

       这时候识别器就需要修改一下了

 

ExpandedBlockStart.gif 代码
<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;

namespace  BeautyCode.Common.ConApp.Head.First.OO.Design
{
    
public   class  BarkRecognizer
    {

        
private  DogDoor3 _door3;
        
public  BarkRecognizer(DogDoor3 door)
        {
            _door3 
=  door;
        }
        

        
public   void  Recognize3(Bark bark)
        {
            Console.WriteLine(
" Bark Recognizer: heard a  "   +  bark);
            
foreach  (Bark b  in  _door3.GetAllowBark())
            {
                
if  (b.Equals(bark))
                {
                    _door.Open();
                    
return ;
                }

            }

            Console.WriteLine(
" this dog is not allow " );
        }
    }
}

 

     

     

  结论
      要注意requirements和use case中的名词,它们通常就是一个类或者是类中的一个属性;其中的动词通常会是一个类的方法。

 

 

强烈推荐 “《深入浅出面向对象分析设计》对OOA&D这个主题的探讨令人耳目一新。 本书众不同之处在于它将焦点摆在学习上,本书的诸位作者让从业人员对OOA&D的内涵不再感到遥不可及,而且它在实际工作中确实有用。”               ——Iva Jacobson Ivar Jacobson Consulting UML之父 “隐匿在诙谐图片逗趣文字背后的是对OOA&D这个主题认真、睿智且极具匠心的阐述。阅读本书,感觉就像站在专家的肩膀上环顾方,聆听他一步步、细心倾诉那些重要的议题,并且告诉我为什么。”             ——Edward Sciore 波士顿学院计算机科学系副教授 “刚读完这本书,我就深深地爱上它了!我最喜欢的一件事就是本书把焦 点放在我们实践OOA&D的原因上一写出伟大的软件!”                         ——Kyle Brown IBM杰出工程师你是否早已对市面上那些只有在成为专家以后读起来才有感觉的OOA&D书籍感到厌倦?你可能早就听说过OOA&D书籍能帮助你写出伟大的软件一让老板高兴、客户满意的软件。 《深入浅出面向对象分析设计》将告诉你如何分析设计以及撰写真正面向对象的软件:容易重利用、好维护、可扩展的软件;不再使你心碎的软件;让你增添新功能而不会破坏旧机制的软件。在本书中,你将学到:   使用诸如封装(encapsulation)委派(delegation)的OO原则建立灵活的应用程序。   使用开闭原则(Open—C10 sed Principle)单一责任原则(Single—Responsibility Principle)提升程序的重利用性。   学习如何将OO原则、设计模式及各种开发方法通通整合到OOA&D项目的生命周期里。   运用UML、用例及用例图来确保所有利害关系人都能清楚地进行沟通,协助你交付正确的软件,达到每个人的要求。   通过一连串的脑力开发,《深入浅出面向对象分析设计》压缩了学习获取复杂信息所需的时间。可以预料,这将是一段充满乐趣的学习之旅。相信在读完本书之时,你肯定能够写出伟大的软件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值