设计模式六大原则:
(1)单一职责原则
(2)里氏替换原则
(3)依赖倒置原则
(4)接口隔离原则
(5)迪米特法则
(6)开闭原则
基本模式:接口、抽象父类、私有方法、访问者方法、常数管理器
创建模式:工厂模式、抽象工厂模式、单例模式、原型模式
结构模式:装饰器模式、适配器模式、责任链模式、外观模式、代理模式、桥接模式
行为模式:命令模式、备忘录模式、观察者模式、策略模式
提高性能:享元模式、单例模式、原型模式
增加系统复杂度:享元模式、迭代器模式、工厂模式、桥接模式、适配器模式
扩展性高:建造者模式、工厂模式、桥接模式
1、享元模式。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。主要用于减少创建对象的数量,以减少内存占用和提高性能。
主要解决:在有大量对象时,有可能会造成内存溢出,我们把其中共同的部分抽象出来,如果有相同的业务请求,直接返回在内存中已有的对象,避免重新创建。
何时使用: 1、系统有大量相似对象。2、这些对象消耗大量内存。
应用实例: JAVA 中的 String,如果有则返回,如果没有则创建一个字符串保存在字符串缓存池里面。
优点:大大减少对象的创建,降低系统的内存,使效率提高。
缺点:提高了系统的复杂度,需要分离出外部状态和内部状态,不能被共享的数据属性,可以被设计为非共享享元类,即享元模式的外部状态。
2、外观模式
定义一个高层接口,使得子系统更容易使用,且隐藏系统的复杂性。
主要解决:降低访问复杂系统的内部子系统时的复杂度。
何时使用:定义系统的入口。
优点: 1、减少系统相互依赖。 2、提高灵活性。
缺点:不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
3、建造者模式
使用多个简单的对象逐步构建成一个复杂的对象。
主要解决:有时候面临着"一个复杂对象"的创建工作
何时使用:一些基本部件不会变,而其组合经常变化的时候。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、若内部变化复杂,会有很多的建造类。
4、迭代器模式
用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
角色构成:定义boolean hasNext, Object next
主要解决:不同的方式来遍历整个聚合对象。
何时使用:遍历一个聚合对象。
优点: 支持以不同的方式遍历一个聚合对象。
缺点:在一定程度上增加了系统的复杂性。
5、责任链模式(CoR模式)
为请求创建了一个接收者对象的链,对请求的发送者和接收者进行解耦。
应用实例: JS 中的事件委托。
优点: 1、降低耦合度。2、允许动态地新增或者删除责任。3、增加新的请求处理类很方便。
缺点: 1、不能保证请求一定被接收。 2 、可能不容易观察运行时的特征,有碍于除错。
案例:
类图
时序图
6、工厂模式
通过使用一个共同的接口来指向新创建的对象,在创建对象时不会对客户端暴露创建逻辑。
主要解决:主要解决接口选择的问题。
如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
优点: 1、只要知道其名称就可以创建一个对象。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,在一定程度上增加了系统的复杂度
7、抽象工厂模式
围绕一个超级工厂创建其他工厂,每个生成的工厂都能按照工厂模式提供对象。
主要解决:主要解决接口选择的问题。
8、单例模式
该类负责创建自己的对象,同时确保只有单个对象被创建。
这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
主要解决:一个全局使用的类频繁地创建与销毁。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
优点:
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(如jQuery)
2、避免对资源的多重占用(比如写文件操作)。
缺点:没有接口,不能继承,与单一职责原则冲突
9、桥接模式
将抽象部分与实现部分分离,使它们可以独立的变化。
主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。
优点: 1、抽象和实现的分离。 2、扩展性高。 3、实现细节对客户透明。
缺点:桥接模式的引入会增加系统的理解与设计难度。
10、适配器模式
将一个类的接口转换成客户希望的另外一个接口。
主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
优点: 可以让任何两个没有关联的类一起运行。
缺点: 过多地使用适配器,会让系统非常零乱。
11、原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。
优点: 性能提高。
12、代理模式
为其他对象提供一种代理以控制对这个对象的访问。
如何解决:增加中间层。
和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
13、命令模式
将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。
14、中介者模式
用一个中介对象来封装一系列的对象交互。
15、备忘录模式
保存一个对象的某个状态,以便在适当的时候恢复对象。
何时使用:允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有"后悔药"可吃。
16、观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象的状态发生改变,所有的依赖对象都将得到通知,进行广播通知。