设计模式基础
设计模式基本含义
- 在什么原则的指导下,进行编程,代码处理的基本策略。(解决标准问题的通用解决方法)
- 软件架构重用。
- 设计模式独立于某种语言,但是需要面向对象语言支持。
设计模式的重要性
- 设计模式是对软件设计中普遍存在的问题提出的。
- 编写软件的过程中,程序员面临来与耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战。设计模式可以改善这些方面。
设计模式的本质: 某类问题的通用解决方案,代表了最佳的实践。
设计模式分类
- 创建型模式(对象创建角度):单例模式,工厂模式,原型模式,建造者模式。
- 结构型模式(软件结构角度):适配器模式,桥接模式,装饰器模式,组合模式,外观模式,享元模式,代理模式。
- 行为性模式(代码方法角度):模板方法模式,命令模式,访问者模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,责任链模式。
七大设计原则
单一职责原则(SRP)
基本内容: 对于类来说,一个类只负责一项职责。如类A负责两个不同的职责,那么当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将A的粒度分解为A1,A2。
作用
- 降低类的复杂度,一个类只负责一项职责。
- 提高类的可读性,可维护性。
- 降低变更引起的风险。
注意事项: 通常情况下,我们应当遵守单一职责原则,只有逻辑足够简单,才能在代码级违反单一职责原则。只有当类中的方法足够少时,才能在方法及保持单一职责原则。
接口隔离原则(ISP)
内容: 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖,应该建立在最小的接口上。
作用: 使系统分离,系统更容易重构,修改和重新部署。
依赖倒置原则(DIP)
内容:
- 高层模块不应该依赖低层模块,二者都应该依赖其抽象。
- 抽象不应该依赖细节,细节应该依赖抽象。
- 依赖倒转的中心思想是面向接口编程。
作用: 相对于细节的多变,抽象的东西更加稳定。以抽象为基础搭建的结构比以细节为基础搭建的结构更加稳定。
注意事项
- 低层模块尽量都要有抽象类或接口,或者两者都有,程序的稳定性更好。(接口和抽象类的目的是制定好规范)
- 变量的声明类型尽量是抽象类或接口,这样我们的变量引用和实际对象之间,就存在一个缓冲层,有利于程序扩展和优化。
里氏替换原则(LSP)
内容: 引用基类的地方,必须能够透明的使用其子类,在使用基类的地方,将基类替换为其子类,程序行为不会改变。
注意事项: 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类方法。
继承性的思考和说明:
- 继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有子类必须遵守这些契约,但是子类如果对这些已经实现的方法任意修改,就会对整个系统造成破坏。
- 继承在给程序设计带来便利的同时,也有弊端。如会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都可能产生故障。
开闭原则(OCP)
!注意: 编程中,最基础,最重要的原则!
内容
- 一个软件实体,类,模块,函数,应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现来扩展细节。
- 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码实现变化。
注意事项: 代码遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
迪米特法则(LOD)
内容: 一个对象应该对其它对象保持最少的了解。(类与类关系越密切,耦合度越大)
注意事项
- 对于被依赖的类,不管多么复杂,都尽量将逻辑封装在类的内部,除了提供的public方法,不对外泄露任何信息。
- 只与直接朋友通信。
- 直接朋友:两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。其中,成员变量,方法参数,方法返回值中出现的类为直接朋友。(局部变量不是直接朋友,也就是说,陌生的类最好不要以局部变量的形式出现在类的内部)
合成复用原则
内容: 在软件开发中,尽量使用依赖/合成/聚合的方式,而不是使用继承。(继承关系有很强的耦合性)
设计原则核心思想
- 找出应用中可能变化的地方,把它们独立出来,不要和哪些不变的代码混合在一起。
- 针对接口编程,而不是针对实现编程。
- 为了交互对象之间的松耦合设计而努力。
设计模式具体内容,会在之后根据不同的分类发出。:>