在开发的过程中,我们所写的程序如同在真空中一样,相对理想的环境,相对较好的机器。然而一旦软件部署到客户端,软件就在现实世界中工作。此时,很多性能和并发的问题就产生了。 让软件在真实的世界中正常工作的关键是分析:在发布你的程序前,指出潜在的问题,然后解决他们。分析帮助你确保你的系统在现实环境中工作。 分析的第一步就是:指出潜在的问题: 回到上一章的故事,还记得那个改进后的Dog Door。现在有了一个新的问题:邻居家的狗叫的时候,这个门也会自动打开。 现在问题发现了,根据问题要重新修改用例。接收到声音信号后,BarkRecognizer要识别是否是这家人的小狗叫。修改后用例如下:(黑色粗体为修改的部分) 从用例中我们可以看出,现在声音识别器在获得音频信号后,要进行比对,以确认这个声音是否为此家人的小狗。这样,我们就要保存一个小狗的声音用来比对。所以我们需要一个新的用例来保存狗的叫声。 用例更新后,程序需要做相应的修改,但是有一个问题出现:如何更改。实际上程序有很多实现方式。如何选择? 有人认为:简单是最好的。既然需要一个对象存储小狗的叫声,当需要的时候进行比对,那我们可以用一个String对象来存储。只需要在Dog Door 对象中进行修改。代码修改如下: public class DogDoor { private String _allowedBark; public String AllowedBark { get { return _allowedBark; } set { _allowedBark = value; } } // } 相应的BarkRecognizer()中也需要修改: public class BarkRecognizer { DogDoor door = new DogDoor(); public void recognizer(String Bark) { if (door.AllowedBark == Bark) { door.Open(); } } // } 也有人更忠实于面向对象。在这种情况下,编写一个Bark类型,并赋予相应的比较方法。 添加Bark类型: public class Bark { private String _sound; public Bark(String sound) { _sound = sound; } public String Sound { get { return _sound; } } public Boolean Equal(Bark bark) { Boolean flag = false; if (bark._sound == _sound) { flag = true; } return flag; } } 当然,Dog Door类型也需要修改,代码如下: public class DogDoor { private Bark _allowedBark; public Bark AllowedBark { get { return _allowedBark; } set { _allowedBark = value; } } // } BarkRecognizer类型中的修改如下: public class BarkRecognizer { DogDoor door = new DogDoor(); public void recognizer(Bark Bark) { if (door.AllowedBark.Equal(Bark)) { door.Open(); } } // } 那么哪一种方式更好呢?在这里要提到一个问题:解耦合。也就是说,你的对象对于其他的对象是独立的,或者说一个对象的变化不会导致其他对象的变化。书中写道:Delegation helps our applications stay loosely couples。意思是说:Delegation帮助我们的程序保持松耦合,对于Delegation的翻译,我一直觉得是代理。但在这里我感觉是封装的意思,不知我的理解是否正确。回到刚才两个方法的讨论:如果对于小狗的叫声存储的是声音文件,比如说WAV,对于第二种方式我们只需要修改Bark类型中的Equal方法就可以,BarkRecognizer类型中不需要修改。Delegation shields your object from implementation changes to other objects in your softwave。 但是现在又出现一个很实际的问题:小狗的叫声可能有很多种,无论哪一种,我们应该让门打开。那么在DogDoor类型中的AllowedBark应该是一组Bark对象,换句话说:AllowedBark应该是List<Bark>类型。 说到这里,一个疑惑出现了,如何确定一个程序中的类型?注意用例中的名词。用例中的名词往往是你系统中所需要实现的类型。那么现在把用例中的名词圈出来。 不难看出,很多名词是系统中需要的类型。当然也有些名词是不需要注意的,如;button owner outside inside 书中提到一个词:textual analysis 文本分析。 Looking at nouns and verbs in your use case to figure out classes and methods is called textual analysis. 回到用例中,注意用例中的第三步:3.If it’s the owner’s dog barking. The bark recognizer sends a request to the door open. Owner’s dog是一个名字,但是我们不需要为dog创建一个类型,因为他是发起者,在系统之外。对于Bark,不要只把关注点放到Bark上,还要注意是the owner’s dog。 现在不难看出用例的重要性。尤其是对文本分析的重要性。
在开发的过程中,我们所写的程序如同在真空中一样,相对理想的环境,相对较好的机器。然而一旦软件部署到客户端,软件就在现实世界中工作。此时,很多性能和并发的问题就产生了。
让软件在真实的世界中正常工作的关键是分析:在发布你的程序前,指出潜在的问题,然后解决他们。分析帮助你确保你的系统在现实环境中工作。
分析的第一步就是:指出潜在的问题:
回到上一章的故事,还记得那个改进后的Dog Door。现在有了一个新的问题:邻居家的狗叫的时候,这个门也会自动打开。
现在问题发现了,根据问题要重新修改用例。接收到声音信号后,BarkRecognizer要识别是否是这家人的小狗叫。修改后用例如下:(黑色粗体为修改的部分)
从用例中我们可以看出,现在声音识别器在获得音频信号后,要进行比对,以确认这个声音是否为此家人的小狗。这样,我们就要保存一个小狗的声音用来比对。所以我们需要一个新的用例来保存狗的叫声。
用例更新后,程序需要做相应的修改,但是有一个问题出现:如何更改。实际上程序有很多实现方式。如何选择?
有人认为:简单是最好的。既然需要一个对象存储小狗的叫声,当需要的时候进行比对,那我们可以用一个String对象来存储。只需要在Dog Door 对象中进行修改。代码修改如下:
相应的BarkRecognizer()中也需要修改:
也有人更忠实于面向对象。在这种情况下,编写一个Bark类型,并赋予相应的比较方法。
添加Bark类型:
当然,Dog Door类型也需要修改,代码如下:
BarkRecognizer类型中的修改如下:
那么哪一种方式更好呢?在这里要提到一个问题:解耦合。也就是说,你的对象对于其他的对象是独立的,或者说一个对象的变化不会导致其他对象的变化。书中写道:Delegation helps our applications stay loosely couples。意思是说:Delegation帮助我们的程序保持松耦合,对于Delegation的翻译,我一直觉得是代理。但在这里我感觉是封装的意思,不知我的理解是否正确。回到刚才两个方法的讨论:如果对于小狗的叫声存储的是声音文件,比如说WAV,对于第二种方式我们只需要修改Bark类型中的Equal方法就可以,BarkRecognizer类型中不需要修改。Delegation shields your object from implementation changes to other objects in your softwave。
但是现在又出现一个很实际的问题:小狗的叫声可能有很多种,无论哪一种,我们应该让门打开。那么在DogDoor类型中的AllowedBark应该是一组Bark对象,换句话说:AllowedBark应该是List<Bark>类型。
说到这里,一个疑惑出现了,如何确定一个程序中的类型?注意用例中的名词。用例中的名词往往是你系统中所需要实现的类型。那么现在把用例中的名词圈出来。
不难看出,很多名词是系统中需要的类型。当然也有些名词是不需要注意的,如;button owner outside inside
书中提到一个词:textual analysis 文本分析。
Looking at nouns and verbs in your use case to figure out classes and methods is called textual analysis.
回到用例中,注意用例中的第三步:3.If it’s the owner’s dog barking. The bark recognizer sends a request to the door open. Owner’s dog是一个名字,但是我们不需要为dog创建一个类型,因为他是发起者,在系统之外。对于Bark,不要只把关注点放到Bark上,还要注意是the owner’s dog。
现在不难看出用例的重要性。尤其是对文本分析的重要性。
对于用例中的动词,实际上是系统重要实现的方法。 完成分析后,明确了系统中需要的类型和方法,我们可以很简单的画出系统的类图。类图中可以描述类型之间的依赖关系。 分析得差不多了,类图也画出来了。虽然类图可以很清楚的表现出类型之间的关系,但是不能告诉我们代码是如何实现的。下面我们来看看代码的实现: 首先编写Bark类型 public class Bark { private String _sound; public Bark(String sound) { _sound = sound; } public String Sound { get { return _sound; } } public Boolean Equal(Bark bark) { Boolean flag = false; if (bark._sound == _sound) { flag = true; } return flag; } } 在DogDoor类型中加入如下代码: private List<Bark> _allowedbarks; public List<Bark> AllowedBarks { get { return _allowedbarks; } set { _allowedbarks = value; } } 修改BarkRecognizer中的recognize方法,代码如下: public void recoginze(Bark bark) { Console.WriteLine(" BarkRecognizer heard a '" + bark.Sound + "'"); foreach (Bark allowbark in _door.AllowedBarks) { if (bark.Equal(allowbark)) { _door.Open(); break; } else { continue; } } } 最后修改测试代码并查看结果: static void Main(string[] args) { DogDoor door = new DogDoor(); door.AllowedBarks.Add(new Bark("Woof")); door.AllowedBarks.Add(new Bark("Yip")); BarkRecognizer recognizer = new BarkRecognizer(door); Remote remote = new Remote(door); Console.WriteLine("The dog is barking, he wanna "); Bark bark1 = new Bark("Woof"); recognizer.recoginze(bark1); Console.WriteLine("The dog is outside and "); Thread.Sleep(10000); Bark bark2 = new Bark("Yip"); Console.WriteLine("The dog is barking, he wanna inside"); recognizer.recoginze(bark2); Console.WriteLine("The dog is inside"); Thread.Sleep(10000); Console.WriteLine("Another dog is barking"); Bark bark3 = new Bark("Hooh"); recognizer.recoginze(bark3); Console.Read(); } 输出结果为:
对于用例中的动词,实际上是系统重要实现的方法。
完成分析后,明确了系统中需要的类型和方法,我们可以很简单的画出系统的类图。类图中可以描述类型之间的依赖关系。
分析得差不多了,类图也画出来了。虽然类图可以很清楚的表现出类型之间的关系,但是不能告诉我们代码是如何实现的。下面我们来看看代码的实现:
首先编写Bark类型
在DogDoor类型中加入如下代码:
修改BarkRecognizer中的recognize方法,代码如下:
最后修改测试代码并查看结果:
输出结果为:
posted on 2007-09-26 17:10 KiddLee 阅读(2184) 评论(12) 编辑 收藏 网摘 所属分类: OOA&D学习与探索系列
昵称: [登录] [注册]
主页:
邮箱:(仅博主可见)
验证码: 看不清,换一个
评论内容:
登录 注册
[使用Ctrl+Enter键快速提交评论]