这段时间一直都在思考怎么样的设计才算得上是面向对象的设计,我们应该怎样学习和搞清楚面向对象的设计模式。下面就针对自己对设计模式的理解和参考其他视频资料、学习资料基础上的学习做一个学习笔记,加深对设计模式的理解和运用,提升自己面向对象的抽象思维。
设计模式的要点:设计模式(Design pattern)的鼻祖来至于建筑学领域。
建筑学定义的模式是:每个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。
然后在软件设计里面,从建筑学那边借鉴过来,软件设计模式描述了在软件设计过程中某一类常见问题的一般性解决方案。通过建筑学和软件设计的不同领域,其实也能看出有很强的类比性。通过对比可以看出,软件设计模式描述了常见问题的一般性解决方案。其实我们知道在软件设计过程中,设计软件其实有很多的陷阱,你可以拿到工具和语言可以做各种各样的事情,解决各种各样的问题。
我理解的是软件设计模式的初衷是通过设计模式去惯性的进行软件设计,碰到一些问题根据我们的经验去选择好的方式去做。
然而面向对象的设计模式描述了在面向对象的设计过程中,特定常见下,类与相互通信的对象之间常见的组织关系。
GoF23中设计模式的理解:这本书《设计模式:可复用性面向对象软件的基础》中描述了23中经典的面向对象设计模式,同时也建立了模式在软件设计中的地位。然后人们通常说的设计模式都隐含的表达是"面向对象的设计模式",但这并不意味着设计模式就等于面向对象的设计模式,其实也意味着GoF23中设计模式并非表示了所有的面向对象的设计模式,除了GoF23中设计模式以外,还有更多的面向对象的设计模式。GoF23种设计模式是经典的模式,它是学习面向对象设计模式的基础,也是起点,而非终点,但是它能够深化我们对面向对象的认识。
面向对象设计模式解决的是:类与相互通信的对象之间的组织关系,如角色、职责、协作等几个方面。一般来说只要成为模式的我们都应该是认为比较好的,所谓面向对象的设计模式是可以满足那些:应对变化,提高复用的设计。敏捷软件开发有一句很重要的话是:源代码就是设计,这其实也是我们不断对软件认识发现的。从早期的软件开发过程来看,大家都一直想把软件设计工程化,像建筑师画好图纸,交给施工单位,在99%的情况下都可以盖的很好。按照这个设计,大家可以根据自己的经验来看,很多工程问题,大致可以分成两个阶段:工程设计阶段和工程实现阶段。其实我们想在软件工程也希望能达到这种模式。但是后来不得不软件太复杂了:"比如架构师或者系统分析员做了设计,交给程序员就会做的很好",这其实是不可能的,这不是说架构师和程序员都不称职,而主要的原因是:软件是变化的。所以敏捷软件开发提出的:源代码就是设计。如果我们把程序员编程的工作也来看成设计的话,我们就可以弄清楚这些关系。这句话的理解对我们是很有帮助的。
另外我们也可以从另外一个角度来理解:我们学习任何一个设计模式,可以说不用设计模式同样可以把软件设计的很好,运行的很正常,但是软件有一个特点:它的变化,复杂的可变性。它一方面是来自于客户需求方面的变动,另一方面也来自于技术方面的变动,方法面面的变动作用力导致软件设计过程中不断的变,因此我们使用面向对象的设计的目的就是管理需求的变化,我们不怕变化,但是我们可以把变化给软件的影响降低。
另外面向对象的设计模式描述的是软件设计,因此它是独立于编程语言的,但是面向对象设计模式的最终实现仍然要使用面向对象的编程语言来体现。因此掌握面向对象的设计模式的前提是首先掌握面向对象。而且我们理解的面向对象和设计模式所要求的面向对象的能力是有差距的,你能够懂语言机制,比如多态,重载,虚函数的重写等,但是你对面向对象理解不深入,你只能看懂代码结构,对设计的一个理念层理解的不深入。导致的结果是:你见到这个模式你认识,你写这个模式也能写出来了,但是在具体的工程实践中,你就会发现这个模式对你没有任何好处,或者用了和没有没什么区别。因此设计模式不可以照搬照用,它是建立在面向对象纯熟,深入的理解的基础上经验性认识的。
编程语言表现面向对象:面向对象的三大机制:
封装:因此内部实现。(和外部隔离,外部接口稳定,内部的实现可以随着版本的升级而改变,但是外部的接口是稳定的)
继承:复用现有代码。
多态:改写对象行为。
PS:
1、使用面向对象的编程语言可以推动我们以面向对象的思维思考软件设计结构,从而强化面向对象的编程范式。
2、面向对象的编程语言认识到的面向对象并不是面向对象的全部,甚至只是表面的。理解了面向对象的三大机制,其实只是在语言层面上理解了面向对象,或者说是在实现层面上理解了面向对象,理解了面向对象是如何在语言上实现的。其实面向对象的一个根本问题是首先是设计,有了设计才有实现,有了一个好的面向对象的设计才会做一个好的面向对象的实现,换言之,理解面向对象的三大机制并不必然理解面向对象的设计,而正确的面向对象的设计,才能导向对面向对象的三大机制有比较好的使用。
面向对象的编程语言没有回答面向对象的根本性问题:我们为什么要使用面向对象?我们应该怎样使用三大机制来实现好的面向对象?我们应该遵循什么样的基本原则?
几条软件设计原则:
单一职责原则(SRP):一个类应该仅有一个引起它变化的原因。
开放封闭原则(OCP):类模块应是可扩展的,但是不可修改(对扩展开发,对更改封闭)
Liskov替换原则(LSP):子类必须能够替换他们的基类。
依赖倒置原则(DIP):高层模式不应该依赖于地址模式,二者都应该依赖于抽象。抽象不应该依赖于实现细节,实现细节应该依赖于抽象。
接口隔离原则(ISP):不应该强迫客户程序依赖于他们不用的方法。
三大基本面向对象设计模式原则:针对接口编程,而不是针对实现编程。优先使用对象组合,而不是类继承。封装变化点。
使用重构得到模式。敏捷软件开发实践提倡的Refactoring to Patterns是目前普遍公认的最好的使用设计模式的方法。