1.1 手写笔记
语雀笔记(这里的要美观一些)
资料来源:
- https://www.bilibili.com/video/BV1uF411t7pK/?spm_id_from=pageDriver&vd_source=8cda1934c6f5a681b91bebf711df3c0c
- https://refactoringguru.cn/design-patterns
- https://www.runoob.com/design-pattern/design-pattern-tutorial.html
1.2 绪论
- 设计模式是面向对象软件设计中常见问题的典型解决方案。
- 算法在数据结构中的定义是:对特定问题求解步骤的一种描述,是指令的有限序列,每条指令代表一个或者多个操作。
- 看起来设计模式和算法在概念上都是对已知问题的解决方案,但是二者不同。算法是为了实现某个目标的一系列具体步骤,每段程序是个算法实现;而设计模式是对解决方案的更高层次描述,每个模式就像一张蓝图,可以看到最终的结果和模式功能,但需要自己通过对其进行定制来解决代码中的特定设计问题,每个模式不是死板的框架,在不同的项目问题中实现代码是可能不同的。
1.2.1设计模式历史
- 模式的概念是由克里斯托佛·亚历山大在其著作 《建筑模式语言》 中首次提出的。 本书介绍了城市设计的 “语言”, 而此类 “语言” 的基本单元就是模式。 模式中可能会包含对窗户应该在多高、 一座建筑应该有多少层以及一片街区应该有多大面积的植被等信息的描述。
- 埃里希·伽玛、 约翰·弗利赛德斯、 拉尔夫·约翰逊和理查德·赫尔姆这四位作者接受了模式的概念。 1994 年, 他们出版了 《设计模式:可复用面向对象软件的基础》 一书, 将设计模式的概念应用到程序开发领域中。为出版方便,将四位作者合称 GOF(四人帮,全拼 Gang of Four)。他们所提出的设计模式主要是基于以下的面向对象设计原则。
● 对接口编程 而不是对实现编程。
● 优先使用对象组合 而不是继承。
此后,人们逐渐发现更多的设计模式,模式方法也在程序开发领域流行起来。
1.2.2 三种主要模式类别
● 创建者模式:这类模式提供创建对象的机制, 能够提升已有代码的灵活性和可复用性。
○ 工厂方法 ○ 抽象工厂 ○ 生成器 ○ 原型 ○ 单例
● 结构型模式:这类模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效
○ 适配器 ○ 桥接 ○ 组合 ○ 装饰 ○ 代理 ○ 外观 ○ 享元
● 行为模式:这类模式负责对象间的高效沟通和职责委派。
○ 责任链 ○ 命令 ○ 迭代器 ○ 中介者 ○ 备忘录 ○ 观察者 ○ 状态 ○ 策略 ○ 模板方法 ○ 访问者
设计模式间关系:
1.2.3 六种原则
1 单一职责
- 一个类仅仅、一个方法只做一件事。职责是指类变化的原因,单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。
- 体现在代码上就是一个父类或者接口只定义所有子类的通用方法,而具体的特殊方法实现就由每个子类单独实现。因为设计模式是面向接口和抽象进行的,所以存在通用方法也就是每个子类的同一种方法的实现逻辑相同时候,可以设计一个抽象父类,子类来继承这一个父类;而其他不同的方法,则定义在接口中,由子类implements多个或者一个接口来实现。
代码示例:
1 抽象父类
public abstract class Animal{
//共有的方法-都是碳基生命
public void common(){
System.out.println("都是碳基生物!");
}
}
2 特殊方法声明接口
public interface IName {
void myname();
}
3 不同子类实现
public class Dog extends Animal implements IName{
void myname(){
System.out.println("我是小狗!");
}
}
//另一个类
public class Cat extends Animal implements IName{
void myname(){
System.out.println("我是小猫!");
}
}
2 开闭原则(Open Close Principle)
- 开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。
- 上面的代码继承和实现也可以体现,抽象类确定了不能被修改的方法,无论哪个子类都是使用父类的方法,而实现接口则进行差异化扩展改变。
3 里氏代换原则(Liskov Substitution Principle)
- 里氏代换原则是面向对象设计的基本原则之一。
- 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。
- 里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
- 2和3真的分不太清,结合到一起就是尽量使用接口和抽象,抽象共同的,扩展接口实现差异化方法。
4 迪米特法则,又称最少知道原则(Demeter Principle)
- 最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。
- 简单来说,就是每个对象负责自己的功能,别互相调来调去,调的多了估计自己都晕。
5 接口隔离原则(Interface Segregation Principle)
- 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。
- 例如兔子类需要实现的方法是蹦蹦跳跳 、 吃草 、打洞,牛类实现的方法是走路、吃草、睡觉;那么这5个方法别都放到一个接口中,如果五个方法都放到一个接口,两个类来实现这个接口,那么将会发生兔子类重写的走路、睡觉是无效代码,虽然没有具体代码实现,但是你得写在类里面,会使代码变得臃肿不好看,牛类同理也会由多余的蹦蹦跳跳 和打洞方法。所以,需要将接口进行隔离,分设两个接口,兔子实现兔子的接口,牛实现牛的接口,互不打扰。
6 依赖倒置原则(Dependence Inversion Principle)
这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。