23种设计模式
设计模式五大原则和一法则
-
单一职责原则(Single Responsibility Principle)(高内聚,低耦合):一个类只负责一项职责,对一个类而言,只能有一个引起他变化的原因
-
里氏替换原则(LSP liskov substitution principle):子类可以扩展父类的功能,但不能改变父类原有的功能(增强程序的健壮性)
-
依赖倒置原则(dependence inversion principle)**:面向接口编程,上层模块不应该依赖下层模块,两者应依赖其抽象
-
接口隔离(interface segregation principle)**:建立单一接口,类之间的依赖关系应该建立在最小的接口上,客户端不应该依赖不需要的接口【接口粒度越小,系统越灵活,但复杂性越高,维护性降低】
-
迪米特原则(law of demeter LOD):最少知道原则,尽量降低类于类之间的耦合;一个对象应该对其他对象有最少的了解
-
总:开闭原则(open closed principle):用抽象构建架构,用实现扩展原则
1.工厂模式:
类别:创建型模式;
功能:提供了一种创建对象的最佳方式;
优点:1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体逻辑实现,调用者只关心产品的接口;
缺点:适合复杂对象适合工厂模式,使得系统中的类的个数成倍增加会增加系统复杂度和具体类的依赖;
使用场景:1、日志记录器:记录可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方。
2、数据库访问,当用户不知道最后系统采用哪一类数据库,以及数据库可能有变化时。 3、设计一个连接服务器的框架,需要三个协议,"POP3"、"IMAP"、"HTTP",可以把这三个作为产品类,共同实现一个接口。
2.抽象工厂模式:
类别:创建型模式;
功能:提供了一种创建对象的最佳方式;
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象;
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
3.单例模式:
类别:创建型模式;
功能:提供了一种创建对象的最佳方式;
优点:1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。2、避免对资源的多重占用(比如写文件操作);
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。;
使用场景:
1、要求生产唯一序列号。
2、WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
3、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
4.建造者模式:
类别:创建型模式
功能:使用多个简单的对象一步一步构建成一个复杂的对象
优点:建造者独立,易于扩展,便于控制细节风险
缺点:产品需有共同点,范围有限制,内部变化复杂,辉有很多的建造类
使用场景:
1、需要生成的对象具有复杂的内部结构
2、需要生成的对象内部属性本身相互依赖
**与工厂模式的区别是:建造者模式更加关注零件装配的顺序。
5.原型模式:
类别:创建型模式
功能:用于创建重复的对象,同时又能保证性能。提供了创建对象的最佳方式,在运行期建立和删除原型
关键代码:继承Cloneable重写clone()方法
优点:性能提高,避开构造函数的约束
缺点:对于已有的类不支持串行化的间接对象或含有循环结构,需实现Cloneable接口
使用场景:
1、资源优化场景
2、类的初始化需要消耗非常多的资源
3、性能和安全要求的场景
4、通过new产生一个对象需要非常多的数据准备或,访问权限
5、一个对象或多个修改者的场景
6、一个对象需要被多个对象访问且修改时可以拷贝多个对象给他们用
7、原型模式一般结合工厂方法模式一起出现,通过clone的方法创建一个对象,通过工厂方法提供给调用者,
======((((这个模式和volatile有啥区别))))=====
6.适配器模式(转换器)
类别:结构型模式
功能:将一个类的接口转换成另一个接口,使不兼容的类可以一起工作
关键代码:适配器继承或依赖已有对象,实现想要的目标接口
优点:可以让两个没有关联的类一起运行,提高了类的复用,增加了类的透明度,灵活性好
缺点:过多使用会让系统零乱,不易整体把握。Java单继承,最多适配一个适配者类
使用场景:有动机的修改一个正常运行的系统的接口,可以考虑使用适配器模式
**适配器是解决正在服役的项目问题
7.桥接模式
类别:结构型模式
功能:使实体类的功能独立于接口实现类,这两种类型的类可被结构化改变而互不影响。(将抽象部分和实现部分分离,使他们可以独立变化)
关键代码:抽象类依赖实现类
优点:抽象和实现的分离,扩展能力强,实现细节对客户透明
缺点:因聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与变成
使用场景:1、一个系统需要在构件的抽象化角色和具体化角色之间增加灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使他们在抽象层建立一个关联关系2、对于不希望使用继承,或因多层次继承导致系统类的个数增加过多的系统3、一个类存在两个独立变化的纬度且这两个类都需要进行扩展
**对于两个独立变化的维度,使用桥接模式非常合适
8.过滤器模式(或标准模式)
类别:结构型模式
功能:获得符合多个条件的对象
使用场景:对一组数据进行分组的情况下,可以定义一个接口,通过实现接口重写过滤方法,比如传入一个集合,将集合中姓刘的人筛选出来,定义方法,遍历传入的集合,将符合条件的数据加入新的集合并返回,总的来说就是传入数据,去掉不符合条件的并返回
9.组合模式(部分整体模式)
类别:结构型模式
功能:使客户程序与复杂元素的内部结构解耦(动态的给一个对象添加一些额外的职责)
关键代码:树枝和叶子实现统一接口,数值内部组合该接口
实例:算术表达式包括[操作数,操作符,另一个操作数],另一个操作符也可以是操作数、操作符和另一个操作数。
优点:高层模块调用简单,节点自由增加
缺点:其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
使用场景:部分,整体场景,树形菜单,文件,文件夹的管理
10.装饰器模式
类别:结构型模式(创建了一个装饰类用来包装原有的类)
功能:保持类方法签名完整性的前提下,提供了额外的功能
关键代码:
1.Component类充当抽象角色,不应该具体实现
2.修饰类引用和继承Component类,具体扩展类重写父类的方法
实例:孙悟空72变,本质还是猴子
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,可以动态的扩展一个实现类的功能
缺点:多层装饰比较复杂
使用场景:扩展一个类的功能,动态的增加功能,动态撤销
11.外观模式
类别:结构型模式
功能:为子系统中的一组接口提供一个一致的界面,降低访问复杂系统的内部子系统的复杂度,简化客户端与其的接口
关键代码:在客户端和复杂系统之间再加一层,在这一层将调用顺序和依赖关系处理好
实例:西京医院便民门诊(ps:哈哈哈哈秀emmm虽然便民关了)
优点:减少系统相互依赖,提高灵活性,安全性
缺点:不符合开闭原则,若要改东西,那么将会很麻烦
使用场景:1.为复杂的模块或子系统提供外界访问的模块
2.子系统相对独立
3.预防低水平人员带来的风险