说说设计原则
来源:互联网 发布:奇爱博士讲电影知乎 编辑:程序博客网 时间:2024/04/30 01:41
面向对象的设计,核心是设计模式和设计原则。
什么是设计模式?简单来说就是,针对反复出现的问题的经典解决方案。
设计模式小史
在20世纪80年代中期,Kent Beck首先提出了软件命名模式的思想。
大约在1994年10月,GOF(Gamma, Helm, Johnson和Vlissides)根据前辈们的经验,总结出23种OO设计模式,其中最常用和有效的模式大概有15个。
2000年的时候Linda Rising写了一本书《Pattern Almanac 2000》,其中列出了大约500种设计模式。
此外,每年都会举行“Pattern Languages Of Programs”(PLOP)会议,算上2011年,该会议已经举办了18次,会议出版模式的年度纲要《Pattern-Oriented SoftwareArchitecture》,包括卷1和卷2等。
问题是什么?
模式太多了,对有经验的设计者来说,详细了解和记住50种以上的模式非常重要,但要记住1000种模式,还是比较困难,如果把时间花在记住模式上面,我们都没时间去编程了。
有人提出了解决方案,找到根本原则就行了,不必拘泥于模式。根据OO设计原则所创造出来的程序最终自然而然的趋向于模式。
设计原则总结
Robert C.Martin在他的《AgileSoftware Development》中提到了11种OO设计原则。
S.O.L.I.D.原则:
1. SRP,单一职责:就一个类而言应该仅有一个引起它变化的原因。职责太多,类就不好理解,不容易维护,不利于重用,还会增加与其他类的耦合,容易受到其他类变化的影响。
2. OCP,开放封闭原则:软件实体(类,模块,函数等)应该对扩展开放,对修改封闭。实现OCP的关键就在于,依赖于抽象,而不是具体的类,抽象的类保持稳定不变,同时通过从这个抽象派生,可以扩展模块的功能。
3. LSP,Liskov替换原则:子类型必须能够替换他们的基类型。OO设计经常遇到的问题是,新派生类的创建会导致我们改变基类,这样做虽然是情非得已,但它会给程序增加很多复杂度。解决的办法:
a) 代码不多时,提取公共部分
b) DBC:design by contract,大家约定一致的用法
c) 在单元测试中指定契约
4. ISP,接口隔离原则:不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它们所在的类层次结构。可以用委托或者多重继承分离接口。
5. DIP,依赖倒置原则:抽象不应该依赖于细节,细节应该依赖于抽象。如果高层模块独立于底层模块,那么高层模块就非常容易被重用,该原则是框架设计的核心。办法是,接口所有权和依赖关系的倒置,让客户拥有抽象接口,而他们的服务者从这些接口派生。
还有6个包的设计原则,前3个原则强调了包的内聚性,可重用性,可开发性:
1. REP,重用发布等价原则:重用的粒度就是发布的粒度。
2. CCP,共同封闭原则:包中所有类对于同一类性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包中所有类产生影响,而对于其他的包不造成任何影响。
3. CRP,共同重用原则:一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
4. ADP,无环依赖原则:包的依赖关系图中不允许出现环。依赖环会造成依赖关系成倍增加,从而给维护和开发造成负担。解决办法:
a) DIP
b) 提取公共部分,会造成包结构变化,抖动和增加
5. SDP,稳定依赖原则:朝着稳定的方向进行依赖。越是被高度依赖的类,越是应该稳定,应该是抽象或者具体而不变的类。
6. SAP,稳定抽象原则:包的抽象程度应该和其稳定程度一致。依赖应该朝着抽象的方向进行。
Craig Larman在他的《Applying UMLand Patterns》中提到的9个原则,称为GRASP(General Responsibility Assignment Software Patterns,通用职责分配软件模式),作者说大多数设计模式可以被视为少数几个GRASP基本原则的特化,这些原则有助于加速设计模式的学习,帮助我们透过大量细节发现应用设计技术的本质:
1. Information Expert,信息专家:将职责分配给信息专家,信息专家是指具有履行职责所需信息的类。
2. Creator,创建者:将创建类A实例的职责分配给类B:
a) B容纳A
b) B聚集A
c) B具有A的初始化数据
d) B记录A
e) B紧密的使用A
3. Controller,控制器:UI层下面第一个接受和协调系统操作的对象是:
a) 外观控制器,代表“系统”,“根对象”,运行的软件设备,或者是主要子系统
b) 发生该系统操作的用例场景
4. Low Coupling,低耦合:减少变化产生的影响,利于重用和维护
5. High Cohesion,高内聚:保持对象有重点,可理解和可管理,同时还有低耦合的作用。
6. Polymorphism,多态:当行为基于类型变化时,使用多态将行为职责分配给行为所变化的类型。
7. Pure Fabrication,纯虚构:当你走投无路,但又不想破坏高内聚和低耦合时,将一组高内聚的职责分配给人为的或便利性的“行为”类,该类并不代表问题领域概念,而是虚构事物,以此来支持高内聚,低耦合和复用性。
8. Indirection,间接性:将职责分配给中介对象,由该对象来协调其他构件或服务,以避免直接耦合。有一句名言“计算机科学中的大多数问题都可以通过增加一层间接性来解决。”还有一句名言“大多数性能问题都可以通过取出一层间接性来解决!”
9. Protected Variation,防止变异:如何设计对象,子系统和系统,使其内部的变化或不稳定性不会对其他元素造成不良影响?识别预计变化或者不稳定之处,分配职责用以在这些变化之外创建稳定接口。很多技术都可以归结为这个原则:
a) Data-Driven Design
b) Interpreter-Driven Design
c) Reflective or Meta-Level Design
d) Uniform Access
e) Service Lookup
f) LSP
g) Law of Demeter迪米特原则,又叫最少知识原则(Least Knowledge Principle,LKP),或者“不要和陌生人说话”:不要历经远距离的对象结构路径,去向远距离的间接对象发送消息。因为对象结构(连接)可能会发生变化,这种不稳定性会导致对象连接耦合的代码破裂,程序遍历的路径越长,也就越脆弱。有时可以用重构中的Remove Middle Man。
《Head First设计模式》中也总结了几个OO原则,去掉一些明显和前面重复的,它们是:
1. 封装变化
2. 多用组合,少用继承,又叫合成/ 聚合复用原则( Composite/Aggregate Reuse Principle 或 CARP )
3. 针对接口编程,不针对实现编程
4. 为交互对象之间的松耦合设计而努力
5. 只和朋友交谈,也就是迪米特原则
6. Hollywood Principle,好莱坞原则:别找我,我会找你。由超类主控一切,当它们需要的时候,自然会去调用子类。
还有几个在Neal Ford的《The productive programmer》中提到的:
1. YAGNI, you ain’t gonna need it:不要添加自认为将来用得到的代码,事到临头再添加。
2. DRY, don’t repeat yourself:去掉重复的代码。
还有一个比较流行的:
1. KISS, keep it simple and stupid:用最简单的方法让程序工作。
想象中的更高境界
这么多设计模式和原则要运用自如还是很困难,难道那些行业专家在OO设计的时候要考虑那么多问题?时时刻刻嘴巴里面念着模式,原则……
我觉得不是这样的。
先来说一说Dreyfus模型,这个模型是我在《Pragmatic Thinking and Learning》中看到的。它指出从新手到专家要经历5个阶段:
1. 新手:在该技能领域经验很少,或者根本没有经验。一个开发人员声称有10年工作经验,但如果只是一年的经验重复9次,他还是新手。新手比较浮躁,遇到错误容易慌张,如果给新手提供与情境无关的规则去参照,他们就会变得很能干。
2. 高级新手:或多或少能摆脱固定的规则,可以尝试独自完成任务,他们不想要全局思维,想快速的解决问题,但由于对情境没有全面的理解,仍难以完全解决问题。
3. 胜任者:开始寻求和运用专家的意见,并有效利用。他们的工作更多是基于谨慎的计划和过去的经验。如果没有更多经验,在解决问题时,他们将难以确定关注哪些细节。
4. 精通者:有全局思维,围绕这个技术,寻找并想了解更大的概念框架。他们能自我纠正,反思以前是如何做的,并修改其做法,期望下一次表现得更好。他们能向他人学习,能根据情境来解决具体的问题。
5. 专家:是各个领域知识和信息的主要来源,不断寻找更好的方法和方式去做事,丰富的经验,在适当的情境中选取和应用这些经验。他们著书写文章,做巡回演讲,他们是当代的巫师。专家根据直觉工作,而不需要理由。一旦你在一个领域成为专家,在别的领域成为专家就变得容易。因为你已经有了现成的获取知识的技能和模型构建能力。
好了,我想说的是什么呢?我想说的是,不要怕有那么多模式和原则,模式啊原则啊,这些具体的规则只能让你启程,不会让你走得更远。
我们需要通过自我认知,在实践中,不断自我纠正,自我反思,主要是要转变思维,从依赖规则向依赖直觉转变;从关注各个方面,向关注相关方面转变;从问题的旁观者装变为问题涉及的系统本身的一部分。
专家是靠直觉的,他们在情境中识别模式的能力已经超越了他们显性的知识。
他们会独孤九剑,他们无招胜有招。
最后希望大家都通过自己的努力成为专家。
- 说说设计原则
- 说说UI设计
- 简单说说设计模式
- 设计原则 - 开闭原则
- 设计原则-开闭原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- 设计原则
- python3 文件和文件夹操作
- 共用查询窗体的一种实现方法(X3)
- bochs的使用心得
- NetBeans 时事通讯(刊号 # 148 - May 28, 2011)
- 关于实时操作系统的性能指标的判定与分析
- 说说设计原则
- 【原创】android 或JAVA中单例的例子
- 多线程
- QSqlRelationalTableModel的setFilter()问题
- sql2005如何還原master數據庫
- 使用cookies实现浏览历史记录功能
- java代码运行顺序-static main
- Reading an unknow number of Inputs
- 我的平行线