设计模式
具体的代码详情码云查看 - 设计模式
七大原则
-
单一职责原则(SRP)
降低类的复杂度,一个类一个功能,或者一个方法一个功能
控制类的粒度,将对象解耦
-
接口隔离原则(ISP)
客户端不依赖它需要的口接口
-
依赖倒转原则
中心思想就是面向接口编程,抽象类不应该依赖细节,细节依赖抽象
面向接口编程
-
里式替换原则(LSP)
子类尽量不要重写父类的方法
-
开闭原则(OCP)
实体如类,模块函数对扩展开放(提供方)最修改关闭(使用)
对扩展开放,对修改关闭
-
迪米特法则
也是最小知道原则,一个类对自己依赖的类越少越好。
只与你直接朋友说话,不和陌生人说话
-
合成复用原则
尽量使用合成/聚合方式,不使用继承
核心思想:找出应用中可能需要变化,把它们独立出来;针对接口编程,不是针对实现编程;为了交互对象之间松耦合设计努力。
UML
基本介绍:统一建模语言,帮助开发人员进行思考和记录思路的结果。
类图:
用来描述系统中的类之间的各种静态关系;
类之间关系:依赖、继承(泛华)、实现、关联、聚合与组合
依赖:是一种使用的关系,即一个类的实现需要另一个类的协助。
继承:它指定了子类如何特化父类的所有特征和行为。
实现:是一种类与接口的关系,表示类是接口所有特征和行为的实现。
关联:是一种拥有的关系,如一对多,多对一,多对多。
聚合:是整体与部分的关系。
组合:是整体与部分的关系,但部分不能离开整体而单独存在。
分类
分为3种类型,共23种
- 创建型模式:单列、抽象工厂、工厂、原型、建造者
- 结构型模式:适配器、桥接、装饰、组合、外观、代理、享元
- 行为型模式:模板方法、命令、访问者、迭代器、观察者、中介者、备忘录、解释器、状态、策略、责任链
创建型模式
单列模式:
一个类只允许创建一个对象,只能存在一个实例。
单例有7种方式:
-
饿汉式(静态常量)
优点:写法简单、在类加载的时候完成实例化,避免线程同步问题。缺点:造成资源浪费;
-
饿汉式(静态代码块)
同上;
-
懒汉式(线程不安全)
优点:有懒加载效果,只能在单线程下使用,线程不安全;
-
懒汉式(线程安全,同步方法)
加synchronized锁,解决线程不安全,缺点:效率低;
-
双重检测
进行双重检测,延迟加载实例化代码只执行一次,线程安全;
-
静态内部类
静态内部类优点:只装载一次,线程是安全的;
-
枚举
可以避免多线程,也能防止反序列化重新创建对象;
工厂模式:
核心本质:实例化对象不再直接new,用工厂方法代替
简单工厂模式
优点:比较好理解,异操作。缺点:违反了ocp原则,对扩展开放,对修改关闭。
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
定义一个创建对象的类,这个类来封装实例化对象的行为。
工厂方法模式
定义一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类。
不修改已有的类的前提下,通过新增的工厂类实现类的扩展
抽象工厂模式
围绕一个超级工厂创建其他工厂,该超级工厂又是其他工厂的工厂。
优点:具体产品在应用层的代码隔离,无需关系创建的细节
缺点:规定了所有被创建的产品集合,产品中扩展新产品比较困难
增加系统的抽象性、理解难度。
原型模式:
用原型实例指定创建对象的种类,通过拷贝这些原型,创建新的对象;
将一个原型对象传给发动创建的对象,对象.clone()
浅拷贝:
对于数据类型是基本数据类型的成员变量,浅拷贝直接进行值传递;是默认的clone()方法实现的。
深拷贝:
复制对象的所有基本数据类型的成员变量值;实现方式1:重写clone()方法,方式2:通过对象序列化。
建造者模式:
是一种对象构建模式,它将复杂对象的建造过程抽象出来。使用者通过制定复杂对象的类型构造出来,具体细节不需要知道。
分为4个角色:
- 产品角色:一个产品对象(例:房子)
- 抽象建造者:产品对象的抽象类
- 具体建造者:实现接口
- 指挥者:构建抽象建造者接口对象,创建复杂对象
主要作用:用户不知道对象的构建过程和细节,就直接创建复杂对象。
结构型模式
适配器模式:
将某个接口转换成期望的另一个接口表示,互相兼容。
主要分为:类适配器模式、对象适配器、接口适配器
使用场景:系统需要使用一些现有的类,而这些类的接口不符合系统的需要。
类适配器模式
缺点:java语言是单继承机制
对象适配器模式
根据合成复用原则,使用组合代替继承
接口适配器模式
可以设置默认的缺省进行适配
桥接模式:
将实现与抽象放在两个不同的类层中,使两个层次都可以独立改变。
桥接模式提高系统的可扩展性,在两个变化的维护中任意扩展一个维护,都不需要修改原有系统,防止类爆炸。
装饰者模式:
动态的将新功能附加到对象上,在对象功能扩展方面,比继承更有弹性,装饰者体现开闭原则。
组合模式:
创建对象组的树形结构,将对象组合成树状结构表示整体部分的层次关系。
组合可以让客户以一致的方式处理个别对象以组合对象。
外观模式:
为子系统中提供一组接口提供一个一致的界面,这个接口更加容易使用。
通过定义一个一致的接口,用以屏蔽内部子系统的细节,使用调用端只需要跟这个接口发送调用。
享元模式:
运用共享技术有效支持大量细粒度对象,常用于底层开发,解决系统的性能问题,常见的数据库连接池。
能解决重复的内存浪费问题,当系统中有大量的相似对象,需要缓冲池。
代理模式:
为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象。
主要有三种静态代理、jdk代理、cglib代理。
静态代理:
需要定义接口、父类;被代理对象、代理对象一起实现相同的接口或继承相同父类。
缺点:一个真实角色会产生一个代理角色,类爆炸。
动态代理:
动态代理类是动态生成的,二不是我们直接写好的。分为:基于接口的动态代理、基于类的动态代理。
基于接口的动态代理:JDK代理;
基于类的动态代理:cglib代理;
行为型模式
模板方法:
在抽象类公开定义执行它的方法的模板,它的子类可以按需重写方法;
模板方法定义一个操作中的算法的骨架,将一些步骤延迟子类中,使子类可以不改变一个算法的结构。
钩子方法:在模板方法父类中,可以定义钩子方法,它默认不做事,子类看情况要不要覆盖它。
命令模式:
请求发送者与请求接受者消除彼此之间的耦合,让对象之间的调用关系关系变的灵活。
在命令模式中,会将一个请求封装为一个对象,便于使用不同参数来表示不同的请求。
访问者模式:
封装一些作用于某种数据结构的各元素的操作,它不改变数据结构的前提下定义作用于这些元素的新操作。
在被访问的类里加一个对外提供接待访问者的接口。
迭代器模式:
我们集合是用不同的方式实现的,有数组、集合类等,我们遍历这些元素使用多种方式,可以使用迭代器模式。
观察者模式:
对象之间多对一依赖,当一个对象获得最新信息,可通知其他相关类得到最新信息。
中介者模式:
用一个对象来封装一系列的对象交互代码。中介者使各个对象不需要显示地相互引用,从而解耦。
例子:MCV模式,C就是中介者。
备忘录模式:
在不破坏封装性下,捕获一个对象的内部状态,在该对象保存这个状态,之后可以将对象恢复到原先的状态。
解析器模式:
一个算法表达式通过词分析器形成词发单元,然后这些词发单元再通过语法分析器构建语法分析树。
状态模式:
主要解决对象在多种状态转换,需要对外输出不同的行为。
当一个对象的内在状态改变,允许改变行为,这个对象开起来是改变其类。
策略模式:
定义算法族,分别封装,让他们之间可以互相替换。
原则:1.把变化的代码从不变的代码分离出来,2.使用接口 3.多用聚合,少用继承
责任链模式:
为请求创建一个接受者对象的链,每个接受者都包含对另一个接受者的引用。