设计模式详解——设计模式初识
一、什么是设计模式
1、概念
设计模式:是指在软件开发中,经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案。
我们从以上标粗的词语中理解一下设计模式的概念
软件开发
解决方案
经过验证
特定环境
重复出现
2、目的
代码重用性
可读性
可扩展性
可靠性
灵活性
高内聚、低耦合
面向对象
3、背景
1995 年,艾瑞克·伽马(ErichGamma)
、理査德·海尔姆(Richard Helm)
、拉尔夫·约翰森(Ralph Johnson)
、约翰·威利斯迪斯(John Vlissides)
4 位作者合作出版了《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)
一书,在本教程中收录了 23 个设计模式,这是设计模式领域里程碑的事件,导致了软件设计模式的突破。这 4 位作者在软件开发领域里也以他们的“四人组”(Gang of Four,GoF)
匿名著称。
本文介绍的设计模式即为上面四位大佬在书中总结的23种设计模式。
二、为什么要学习设计模式
个人技术能力的提升
避免重复造轮子
三、设计原则
在软件开发中,程序员应该尽量遵循一些基本原则来保证程序的健壮性、可扩展性、灵活性等。业内一般遵从以下七种设计原则:
1、单一职责原则
单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分
通俗来说,就是一个类尽量只负责一项功能。例如类A负责功能P1
和P2
,如果P1
功能需要修改,就需要修改类A
,由于P2
功能也在类A中,就可能导致P2
功能受到影响。
我们在开发中一个类尽量不要被赋予过多的功能,理想状态下一个类只负责一个功能,这样可以最大程度减少一个功能的修改对其余功能的影响。
2、接口隔离原则
一个类对另一个类的依赖应该建立在最小的接口上
即一个类尽量不要依赖自己用不到的接口。例如接口I
有方法fun1
和fun2
,类A
和类B
都依赖这个接口,但是类A
只使用到fun1
,类B只使用到fun2
,这样导致类A使用不到fun2
方法,却被迫需要实现,类B
同理。合理的方案是将接口I拆分成两个接口分别给类A
和类B
使用。
3、依赖倒置原则
高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象
核心思想:面向接口编程,不要面向实现编程。举个栗子,类A
直接依赖类B
,假如要将类A改为依赖类C
,则必须通过修改类A的代码来达成。这种场景下,类A
一般是高层模块,负责复杂的业务逻辑;类B
和类C
是低层模块,负责基本的原子操作;假如修改类A
,会给程序带来不必要的风险。因此可以将类A修改为依赖接口I
,类B
和类C
各自实现接口I
,类A
通过接口I
间接与类B
或者类C
发生联系,则会大大降低修改类A
的几率。
4、里式替换原则
继承必须确保超类所拥有的性质在子类中仍然成立
通俗来讲就是,子类可以扩展父类的功能,但不能改变父类原有的功能。即子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法
5、开闭原则
软件实体应当对扩展开放,对修改关闭
当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。即我们的程序尽量满足一定的扩展灵活性。开闭原则是面向对象程序设计的终极目标,它使软件实体拥有一定的适应性和灵活性的同时具备稳定性和延续性
6、迪米特法则
如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用
目的就是降低类之间的耦合度,提高模块的相对独立性。即高内聚、低耦合。
7、合成复用原则
在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现
在面向对象编程中,继承一定程度上会破坏封装,因为继承将基类的实现细节暴露给子类。同时如果基类发生变化,很可能会影响它的所有子类。因此在实际开发中尽量使用组合/聚合方式,减少联动影响。
四、设计模式分类
设计模式一般有两种分类方法(下面只列出设计模式的名称,具体细节关注后续的文章吼)
1、按照模式的目的分
1.1、创建型模式
单例模式
工厂方法模式
抽象工厂模式
原型模式
建造者模式
1.2、结构型模式
代理模式
适配器模式
桥接模式
装饰模式
外观模式
享元模式
组合模式
适配器模式
1.3、行为型模式
策略模式
模板方法模式
命令模式
职责链模式
状态模式
观察者模式
中介者模式
迭代器模式
访问者模式
备忘录模式
2、按照模式的作用范围分
2.1、类模式
工厂方法模式、适配器模式、模板方法模式、解释器模式
2.2、对象模式
除了上面四种的剩余部分
评论