from wikipedia:Design patterns gained popularity in computer science after the book Design Patterns: Elements of Reusable Object-Oriented Software was published in 1994 by the so-called "Gang of Four" (Gamma et al.). Java is a programming language originally developed by James Gosling at Sun Microsystems (which is now a subsidiary of Oracle Corporation) and released in 1995 as a core component of Sun Microsystems' Java platform.
来这里学习 呵呵 头五项原则是关于类设计的,它们是: SRP,单一职责原则,一个类应该有且只有一个改变的理由。 OCP,开放封闭原则,你应该能够不用修改原有类就能扩展一个类的行为。 LSP,Liskov替换原则,派生类要与其基类自相容。 DIP,依赖倒置原则,依赖于抽象而不是实现。 ISP,接口隔离原则,客户只要关注它们所需的接口。 另外的六项是关于包的设计原则。在本文中,包是指一个二进制的可发布文件,比如.jar文件、或dll文件,而不是Java包或是C++的命名空间(译注3)。 头三项包原则是关于包内聚性的,它们会告诉我们该把什么划分到包中: REP,重用发布等价原则,重用的粒度就是发布的粒度。 CCP,共同封闭原则,包中的所有类对于同一类性质的变化应该是共同封闭的。 CRP,共同重用原则,一个包中的所有类应该是共同重用的。 最后的三项原则是关于包之间的耦合性原则的,并且论述了评价系统中包结构优良与否的评判标准。 ADP,无环依赖原则,在包的依赖关系图中不允许存在环。 SDP,稳定依赖原则,朝着稳定的方向进行依赖。 SAP,稳定抽象原则,包的抽象程度应该和其稳定程度一致。 译注: 1,OOD,全称Object Oriented Design,即面向对象设计。 2,PPP,即Bob大叔的著作《敏捷软件开发 原则、模式与实践》一书以及其相关书籍,因都有“原则、模式与实践”,即Priciples, Patterns and Practices,故常简称为PPP。 3,命名空间,原文为namespace,也译作名字空间。它是一种特殊的作用域,它包含了处于该作用域内的所有标示符,且本身也用一个标示符来表示,这样便于将一系列在逻辑上相关的标示符用一个标示符来组织。就Java编程语言来说,命名空间是通过java包来表达的,所有代码都归属与一个包。来自其他包中的代码要通过指定包名来引用某项特定的标示符,例如,包java.lang中的String类要通过java.lang.String的形式引用。在C++中,命名空间常用来避免命名冲突,尽管现今的C++语言对命名空间做出了扩展,但过去的C++代码很少使用此项功能。 (原文链接网址:http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod; Robert C. Martin的英文blog网址: http://www.butunclebob.com/ArticleS.UncleBob) 作者简介:Robert C. Martin是Object Mentor公司总裁,面向对象设计、模式、UML、敏捷方法学和极限编程领域内的资深顾问。他不仅是Jolt获奖图书《敏捷软件开发:原则、模式与实践》(中文版)(《敏捷软件开发》(英文影印版))的作者,还是畅销书Designing Object-Oriented C++ Applications Using the Booch Method的作者。Martin是Pattern Languages of Program Design 3和More C++ Gems的主编,并与James Newkirk合著了XP in Practice。他是国际程序员大会上著名的发言人,并在C++ Report杂志担任过4年的编辑。
不具体看Robert C. Martine提出的后边6条原则了。说说背景。我们都知道,在上个世纪80年代后期,面向对象技术分为三大流派:Booch、OMT和OOS。其中OMT方法最为成熟和一致,可以说没有它的奠基就不可能有统一的UML。然而UML的出现很大程度上跟Rational公司的商业和技术的巨大成功有关,这个公司也收编了OMT的创始人OOS的创始人,成为自己公司的员工。Rovert C. Martine是Booch方法的忠实传播者,也是Rational公司的员工,所以虽然他随后在面向对象系统分析和设计方面非常出名,但是其技术流派早期一直是Booch的。因此,他所画的UML图中,总是把方法当作对象类来处理,而不是像OMT那样去做比较纯粹的OOAD分析和设计。但是在20世纪后期,Martine转向XP了。不过他获得极高声誉的《敏捷软件开发:原则、模式与实践》这本书中其实还是大量用了他转向XP之前的许多年准备写UML的书的资料,所以这一本书并不是敏捷开发的正宗教材,而是还是有很多繁冗的跟这本书的书名、目的不太相符东西。其中,所谓面向对象11条原则的后6条,就有明显的这些特性。
用继承的话,得用基本人类都有属性作为父类。
“男人”、“女人”分别给添加人xingqiguan属性。
要是设计“人妖”、“天生残疾”呢?如果基类设计的不好这个时候就得改设计方案了。如果把qiguan都作为一个类,新建其他类型的“人”,直接往上面添加就的。残疾人少加点,男人多加点,人妖再多加点。
不是!从系统设计上,接口也是继承的一种形式,class跟interface是不用区分的。所谓组合,是指仅仅在属性、事件、方法上使用其它类型,而不是在自身类型定义上声明。
继承interface仅仅表示事物的行为是同一的,不要求两个事物本质相同。interface仅仅是个行为契约,约束范围比class要弱。两个事物行为同一时,本质不一定同一。例如:石墨可以写字,小刀也可以刻字,这说明它们具有相同的行为,可以继承同一个interface。但若要论本质,石墨本质上是一种矿石,应该去继承矿石基类,小刀本质上是一种工具,应该去继承工具基类,不能混淆。
两个事物本质同一时,行为也不一定同一。例如:石墨和钻石本质上都是矿石,都继承自矿石基类,但石墨可以在纸上划字,所以可以继承“写字interface”,但钻石没法在纸上划字,就不能继承这个接口。
呵呵
头五项原则是关于类设计的,它们是: SRP,单一职责原则,一个类应该有且只有一个改变的理由。
OCP,开放封闭原则,你应该能够不用修改原有类就能扩展一个类的行为。
LSP,Liskov替换原则,派生类要与其基类自相容。
DIP,依赖倒置原则,依赖于抽象而不是实现。
ISP,接口隔离原则,客户只要关注它们所需的接口。
另外的六项是关于包的设计原则。在本文中,包是指一个二进制的可发布文件,比如.jar文件、或dll文件,而不是Java包或是C++的命名空间(译注3)。 头三项包原则是关于包内聚性的,它们会告诉我们该把什么划分到包中: REP,重用发布等价原则,重用的粒度就是发布的粒度。
CCP,共同封闭原则,包中的所有类对于同一类性质的变化应该是共同封闭的。
CRP,共同重用原则,一个包中的所有类应该是共同重用的。 最后的三项原则是关于包之间的耦合性原则的,并且论述了评价系统中包结构优良与否的评判标准。 ADP,无环依赖原则,在包的依赖关系图中不允许存在环。
SDP,稳定依赖原则,朝着稳定的方向进行依赖。
SAP,稳定抽象原则,包的抽象程度应该和其稳定程度一致。
译注: 1,OOD,全称Object Oriented Design,即面向对象设计。 2,PPP,即Bob大叔的著作《敏捷软件开发 原则、模式与实践》一书以及其相关书籍,因都有“原则、模式与实践”,即Priciples, Patterns and Practices,故常简称为PPP。 3,命名空间,原文为namespace,也译作名字空间。它是一种特殊的作用域,它包含了处于该作用域内的所有标示符,且本身也用一个标示符来表示,这样便于将一系列在逻辑上相关的标示符用一个标示符来组织。就Java编程语言来说,命名空间是通过java包来表达的,所有代码都归属与一个包。来自其他包中的代码要通过指定包名来引用某项特定的标示符,例如,包java.lang中的String类要通过java.lang.String的形式引用。在C++中,命名空间常用来避免命名冲突,尽管现今的C++语言对命名空间做出了扩展,但过去的C++代码很少使用此项功能。
(原文链接网址:http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod; Robert C. Martin的英文blog网址: http://www.butunclebob.com/ArticleS.UncleBob) 作者简介:Robert C. Martin是Object Mentor公司总裁,面向对象设计、模式、UML、敏捷方法学和极限编程领域内的资深顾问。他不仅是Jolt获奖图书《敏捷软件开发:原则、模式与实践》(中文版)(《敏捷软件开发》(英文影印版))的作者,还是畅销书Designing Object-Oriented C++ Applications Using the Booch Method的作者。Martin是Pattern Languages of Program Design 3和More C++ Gems的主编,并与James Newkirk合著了XP in Practice。他是国际程序员大会上著名的发言人,并在C++ Report杂志担任过4年的编辑。
“继承、封装、多态”作为原则是上个世纪80年代后期的事了。lz的问题里谈的GOF所给出的这个观念,是上个世纪90年代的事。而面向对象设计的11条原则则是代表着上个世纪最后2年的事,那个时候过分玩UML图也已经被广泛批评,于是才出现了敏捷开发。
谢谢sp1234通过反问的形式提醒我的疏漏。在9楼我说了要区分事物本质,注意里氏替换原则,却漏了说明非常重要的一点:区分事物本质是要考虑事物所处的环境。因为以不同的观点看同一个事物,也会得到不同的结果。
例如开发一个鸵鸟和鸟的系统,如果这个系统是用来考察鸟类的羽毛,鸵鸟自然应该继承鸟基类。但若系统是用来考察鸟类的飞行速度,很自然,鸵鸟就不适合继承鸟基类了,它根本就不会飞。
借用一下sp1234先生的例子,在外贸订单系统中,如果能区分出考察“外贸订单”的环境,就不会迷惑了:在系统的业务逻辑层,“外贸订单”就是属于一类订单,因为在这层要处理订单的现实逻辑关系。而在系统的展示层,“外贸订单窗体”本身不是“订单”,本质上讲它是用来展示订单数据的界面,这样它继承Form类也就是很自然的事情了。如果非让“外贸订单窗体”继承一个接口的话,它不应该继承“I订单”接口,而应该继承“I显示订单”接口。系统业务层考察订单的现实逻辑,系统展示层考察订单的显示逻辑,考察视角的不同,结果“外贸订单”是系统的两个层里面大不相同。所以设计系统里的类时,要注意根据系统的使用范围判断类的继承逻辑,如果一个系统不是考察分子、原子的组合,那么就不应该从物质物理组成的角度区分事物本质。就算确定了系统范围,实现这个系统也会有多种方法,不会是“只能”这么做或“只能”那么做,要根据你面对的实际情况(比如你团队的技术实力等)做出最适合你的选择。另外,就算是真理也有适用范围,更何况我是无名小辈,说的话连真理都算不上。所以请楼主自己思考,万一我说的话有错,不要误导了楼主。再次感谢sp1234先生,及时指出了我的疏漏。
好处就是组合在扩展会更加灵魂(其代表就是策略模式 你还是看看<Head First设计模式>把)另外补充一下
sp1234的观点不适合初中级别的人 他是更高层次的思维
已经是"心中有刀 心中无刀"古龙小说里面所说的高手境界了
但我们初中级别的还是练练招式把
使用过才知道好坏 这个是一个必须的过程
他总想把他十几年的功力传给我们 不考虑我们会不会消化不良
一、先纠正
这条原则属于面向对象的设计原则二、关于楼主所提问题的答覆
好处是更灵活,简化类的继承体系,减小设计的复杂度[这个需要仔细体悟],你可以以策略模式作为研究对象,它就是用的聚合,你想一下,如果用继承会怎么样,有哪些坏处。三、关于面向对象设计原则、设计模式、OOP之间的关系
OOP三大要素是应用面向对象设计原则、设计模式的语言基础。它是OOPL所固有的。
关于设计模式有一个重要的概念:模式不是一开始就有的,而是不断重构出来的。那么既然是重构出来的,那么是如何重构出来的呢?我们在重构时总有一个目标吧。不能看代码不顺眼就改。我们重构所根据的就是面向对象的设计原则。ok。有人看了Martin flower的《重构》,说:重构不是根据原则,而是根据一堆的方法。如重命名方法、上移方法、提炼类……
那么这些方法的实质是要达到一个怎样的目标呢?就是面向对象的设计原则。ok。可能还有些词不达意。有很多想说的没说出来。