这次的学习内容主要是设计过程中的启发式方法和设计实践中的一些经验。
对于具体的编程工作来说,期待确定性的行为是很正常的,由于软件设计是非确定性的,灵活熟练地运用一组有效的启发方法(试探法),便成了合理的软件设计的核心工作。
1、在确定设计方案时,首选且最流行的方法是面向对象的方法,此方法的要点是辨别现实世界中的对象以及人造的对象。这个过程分为以下几步:辨识对象及其属性、确定可以对各个对象进行的操作、确定各个对象能对其他对象进行的操、确定对象的哪些部分对其他对象可见、定义每个对象的公开接口。
2、抽象是一种能让你在关注某一概念的同时可以放心地忽视其中一些细节的能力。人们一直在使用抽象,当你把一个东西称为“房子”而不是玻璃、木材和钉子构成的组合体时,你就是在用抽象了。以复杂度的观点来看,抽象的主要好处在于它使你能忽略无关的细节。优秀的程序员会在子程序接口的层次上、在类接口的层次上以及包接口的层次上进行抽象,这样才能更快、更稳妥地进行开发。
3、封装填补了抽象留下的空白。抽象是说:“可以让你从高层的细节来看待一个对象。”而封装则说:“除此之外,你不能看到对象的任何其他细节层次”。
4、当继承能简化设计时就继承,继承的好处在于它能很好地辅佐抽象的概念。继承是面向对象编程中最强大的工具之一。如果使用得当,它能带来极大的益处,然而如果使用不当,它也有极大的弊端。
5、信息隐藏是软件的首要技术使命中格外重要的一种启发方法,因为他强调的就是隐藏复杂度。在设计一个类的时候,一项关键性的决策就是确定类的哪些特性应该对外可见,哪些特性应当隐藏起来。类很像是冰山:八分之七都是处于水面之下,而你只能看到水面上的八分之一。信息隐藏中所说的秘密主要分为两大类:隐藏复杂度、隐藏变化源。信息隐藏的障碍包括:信息过度分散、循环依赖、把类内数据误认为全局数据、可以觉察的性能损耗。
6、找出容易变化改变的区域,适应这些变化。过程包括:找出看起来容易变化的项目、把容易变化的项目分离出来、把看起来容易变化的项目隔离开来。常见的容易变化的区域包括业务规则、对硬件的依赖性、输入和输出、非标准的语言特性等。
7、保持松散耦合。模块之间的好的耦合关系会松散到恰好能使一个模块能够很容易地被其他模块使用,尽量使你创建的模块不依赖或很少依赖其他模块。耦合的种类包括简单数据的参数耦合、简单对象耦合、对象参数耦合(更紧密一些)、语义上的耦合(应尽量避免)。
8、设计模式精炼了众多现成的解决方案,可用于解决很多软件开发中最常见的问题。大多数问题都和过去遇到过的问题类似,可以使用类似的解决方法或者模式加以解决。设计模式的好处是:设计模式通过提供相现成的抽象来减少复杂度、设计模式通过把常见解决方案的细节予以制度化来减少出错、设计模式通过提供多种设计方案而带来启发性的价值、设计模式通过把设计对话提升到一个更高的层次上来简化交流。
一些良好的设计实践:
1、设计是一种迭代过程。当你在备选的设计方案之中循环并且尝试一些不同的做法时,你将同时从高层和底层的不同视角去审视问题。这种高低层次之间的互动被认为是一种良性的原动力,他所创造的结构要远远稳定于单纯自上而下或者自下而上创建的结构。当你首次尝试得出了一个看上去足够好的设计方案后,请不要停下来!第二个尝试几乎肯定会好于第一个。
2、分而治之,把程序分解为不同的关注区域,然后分别处理每一个区域。如果你在某个区域里碰上了死胡同,那么就迭代。
3、采用自上而下和自下而上的设计方法。自上而下是从一般的类出发,一步步地把他们分解为更具体的类。自下而上是从知道的东西入手,找出具体的对象和职责,再找到通用的对象,逐步向上。两种方法各有优缺点,但这两种方法不是相互排斥的——你会收益于两者的相互协作。
4、建设实验性原型可以帮助判断一种设计方法是否奏效,内容是写出用于问题特定设计问题的、量最小且能够随时扔掉的代码。
5、要学会合作设计,三个臭皮匠顶得上一个诸葛亮。
6、要做多少设计取决于团队的经验、系统的预定寿命、得到的可靠度、项目的规模等。
《代码大全》学习摘要(五)软件构建中的设计(下),布布扣,bubuko.com