首页 > 代码库 > 设计模式之设计原则
设计模式之设计原则
个人理解:
设计模式的原则指明了我们在设计类型的时候需要考虑到的方面。在现实应用中,很难有符合所有设计原则的实现。程序员们需要根据实际需要来决定应用哪些原则,舍弃哪些原则。
学习设计模式要求对面向对象有一定了解,另外最好能够看懂UML类图。
关于面向对象,大学老师曾经说对象是对现实事物的抽象,而且还提供了一套从需求描述中提取对象(名词),属性(名词),方法(动词)的理论。这种理解在比较长的时间里给了我很多困扰——项目中有很多类应当合并成一个类,因为他们映射到了同一个现实事物。直到在《松本行弘的程序世界》上读到这样的解释:面向对象不过是在面向过程的基础上提供了数据复用的功能(后者提供了算法复用的功能)。从这个日本人的说法上看,设计模式显得更容易理解。这里如果有大侠能够就如何理解面向对象指教一二,在下亦感激不尽!
关于UML,大多文章/书中的类图并没有严格遵循UML规范,而是提供了示意图,所以基本上能理解这四种关系的UML表示即可:继承、实现、组合(基本不会区分组合和聚合)、依赖。个人也觉得实际中的UML没有必要太严格,因为通过UML生成代码的想法已经被实践证明是不那么理想,而且在敏捷思想中UML也只是作为在白板上沟通的临时性工具(敏捷不提倡设计文档)。
设计原则有六条,可以记为:SOLID原则(有两个L),具体如下——
1. Single Responsibility Principle(单一职责原则)
字面意思是一个类/接口应该只负责一件事情。个人感觉《设计模式之禅》中的说法在理:应该确保引起一个类变化的原因只有一个。
2. Open/Closed Principle(开闭原则)
这个应该是最高心法,绝大多数设计模式都可以映射到这个原则。
所有软件模块(模块、类、方法)都应该对扩展开放,对修改关闭。即添加新功能不应修改原来的代码,而是通过新增一个类/方法来实现。这样的好处是添加了新功能的同时不会对原系统造成任何影响,因为没有东西被修改(当然使用新功能的地方无可避免的需要修改)。零修改是理想状态,实际中应让修改尽量小。
3. Liskov Substitution Principle(里氏替换原则)
所有出现父类对象的地方都应该可以使用子类对象替换。
这个原则指出实现子类时应该注意的事项:
a. 子类必须完全实现父类方法;
b. 子类的重名方法参数范围应该比父类方法参数范围大,返回值比父类方法返回值范围小——这样替换后仍然是父类的方法被调用。
Note: A :B(A继承B),则A的范围比B大
4. Law of Demeter(迪米特法则),亦称Least Knowledge Principle(最少知识原则)
一个对象对另一个对象的了解应该尽量少。对象之间不应做没必要的沟通。
这些词和这个原则想表达的意义相近:低耦合、封装。比方说我找你借个橡皮,你把文具盒给我递过来,那我就可能就会在你不知情的情况下使用你文具盒里面的其他东西;再如上学时如果你帮别人传过小纸条,那想想你当时是不是很多余?
5. Interface Segregation Principle(接口隔离原则)
接口应该尽量小(许多接口只有一个方法)。客户端(接口的使用者)不应当依赖于它不需要的接口(方法)。
好处就是针对每个接口都可以单独的扩展。实际中如果从业务角度这个接口没有变化的可能,那么不需要考虑这个原则。
比如如果一个Web Service包含两个方法,有两个Client分别使用了两个方法,如果一个方法的声明(比方参数)变了,那么这两个Client都需要更新;而如果一个Web Service只包含一个方法,那就只需要更新那个引用了的Client。
6. Dependency Inversion Principle(依赖倒置原则)
抽象(抽象类、接口)不应依赖于具体(实现类);高层模块不应依赖于底层模块,二者都应依赖于抽象。
由于抽象没有实现细节,所以其变化的可能性更小,更稳定。依赖于抽象降低了模块间的耦合度,使得框架更稳定。在实践中我们应尽量使抽象保持稳定,因为抽象的变化意味着依赖于抽象的模块都需要改动。
设计模式之设计原则