单例模式有八种方式:
特点:可以避免线程同步问题,但可能造成内存浪费
2. 饿汉式(静态代码块)
3. 懒汉式(线程不安全)
4. 懒汉式(线程安全,同步方法)
上synchronized锁==效率低==,不推荐使用
5. 懒汉式(线程安全,同步代码块)
这种方法也不能起到线程同步的作用!!!可能在if判断发生同步问题!
拒绝使用这种方法~!!
6. 双重检查
volatile 保证数据的可见性,让线程内存数据的变化立刻显示到主存中,而且有序性可以避免指令重排,但是不保证原子性。
7. 静态内部类(推荐使用)
外部类加载时,静态内部类不会立即加载,静态内部类只加载一次,线程安全。
JVM加载类的时候线程安全。
8. 枚举(可以避免反射机制的破坏)
推荐使用!
核心本质:
三种模式:
简单工厂模式(静态)
抽象接口
各种具体实现类
工厂类:每次新增具体实现类都得添加代码,破坏了开闭原则
调用
工厂方法模式
每个抽象接口对应的具体实现类都有对应的工厂方法。
抽象接口
抽象工厂接口
各种具体实现类和其对应的工厂方法
奔驰车:
宝马车:
调用
虽说简单工厂模式破坏面向对象的开闭原则,但是实际业务用的多的还是简单工厂模式,因为工厂方法模式的代码复杂不利用管理。
抽象产品族各接口
华为系列产品(同个产品族)
小米系列产品(同个产品族)
抽象产品工厂
各个产品族的产品工厂
总结:不可以增加产品,但是可以增加产品族。
具体的产品对象
设置抽象的建造者
具体的建造者继承抽象的建造者,实现抽象方法
核心:指挥者类,负责实例化创建对象,根据传入的具体建造者的对象,创建不同的具体对象,同时可以调整建造方法顺序
测试
进一步优化,去掉指挥者,使用静态内部类,修改抽象建造者类,且具体产品赋予默认值
测试
总结:
使用Object的clone方法进行克隆,bean对象实现Cloneable接口,实现父类的clone()方法,里面有方法引用的需要进行属性克隆。
定义:将一个类的接口转换成客户希望的另外-一个接口。 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作!
角色分析:
想要调用的目标类
适配器接口
适配器实现类
需要适配的类
测试
品牌抽象接口
各具体品牌类
抽象的电脑类型类
具体的电脑类型实现类
测试组装起来
好处分析:
劣势分析:
使用的场景:
总结:如果一个类存在两个独立变化的维度,且这两个维度都需要进行扩展,或者不希望使用继承或者多层级继承导致类数量变多的系统,就可使用桥接模式。特别可以让程序同时适用Linux,window等系统时可以使用该模式。
装饰者模式: 动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
IO流中的InputStream 是抽象类,为被装饰者,
FileInputStream 是 InputStream的子类,
FilterInputStream 是 InputStream 子类,作为修饰者,
DataInputStream 是 FilterInputStream子类,作为具体的修饰者
FilterInputStream类有 protected volatile InputStream in; 即含被装饰者
基本介绍:
解决问题的类型:组合模式解决当我们的要处理的对象可以生成一颗树形结构,而我们要对树上的节点和叶子进行操作时,它能够提供-致的方式,而不用考虑它是节点还是叶子。
抽象类
大学类
学院类
最底层的叶子节点类→系
测试
基本介绍:
基本关系:
子系统类TV
子系统Player
外观模式管理器类
测试
基本介绍:
网站抽象类
具体实现类(可共享的内部状态)
用户对象为外部状态不可共享
享元工厂类
测试
附加例子:jdk中的Integer的valueof产生的对象, 数值如果是-128~127之间的对象是相同的,缓存池的作用。
基本介绍:
静态代理
角色分析:
抽象角色类
真实角色类
代理角色类
客户类
优点:
缺点:
动态代理
基本介绍:
抽象角色类
真实角色类
代理角色类
客户类
Cglib代理
与动态代理的区别,目标对象不用实现任何接口,需要导入Cglib的相关jar包才能实现。
目标对象类
代理类
客户类测试
抽象模板类
各种具体类
测试调用
基本介绍:
抽象命令类
电灯对象(命令接收者)
电灯开的类
电灯关的类
空命令,防止无效命令
控制器(命令发送者)
用户测试类
注意点:
基本介绍:
访问动作抽象类
动作具体实现类
被访问者抽象类
被访问者具体实现类
管理者类
测试类
优点:
缺点:
基本介绍:
学院抽象类
学院具体实现类
自定义的学院迭代器
迭代输出类
测试
优点:
缺点:
观察者模式: 对象之间多对一-依赖的一 种设计方案,被依赖的对象为Subject,依赖的对象为Observer, Subject通知Observer变化。
优点:
Subject类:首先定义一个观察者数组,并实现增、删及通知操作。它的职责很简单,就是定义谁能观察,谁不能观察,用Vector是线程同步的,比较安全,也可以使用ArrayList,是线程异步的,但不安全。
抽象观察者Observer类:观察者一般是一个接口,每一个实现该接口的实现类都是具体观察者。
具体主题子类:继承Subject类,在这里实现具体业务,在具体项目中,该类会有很多变种。
具体观察者:实现Observer接口。
客户端测试类
基本介绍:
1) Mediator 就是抽象中介者,定义了同事对象到中介者对象的接口
2) Colleague 是抽象同事类
3) ConcreteMediator 具体的中介者对象, 实现抽象方法, 他需要知道所有的具体的同事类,即以一个集合来管理HashMap,并接受某个同事对象消息,完成相应的任务
4) ConcreteColleague 具体的同事类,会有很多, 每个同事只知道自己的行为, 而不了解其他同事类的行为(方法), 但 是他们都依赖中介者对象
抽象同事类
具体同事类
抽象中介类
具体的中介者类
优点:
缺点:
基本介绍:
人物初始值类
状态类
备忘录对象类
测试
注意点:
1) 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2) 实现了信息的封装,使得用户不需要关心状态的保存细节。
3) 如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存, 这个需要注意。
4) 适用的应用场景:
1、后悔药。
2、打游戏时的存档。
3、Windows 里的 ctri + z。
4、IE 中的后退。
5、数据库的事务管理
5) 为了节约内存,备忘录模式可以和原型模式配合使用。
基本介绍:
1) Context: 是环境角色,含有解释器之外的全局信息.
2) Abstractexpression: 抽象表达式, 声明一个抽象的解释操作,这个方法为抽象语法树中所有的节点所共享
3) Terminalexpression: 为终结符表达式, 实现与文法中的终结符相关的解释操作
4) NonTermialexpression: 为非终结符表达式,为文法中的非终结符实现解释操作.
5) 说明: 输入 Context he Terminalexpression 信息通过 Client 输入即可
解释器封装类
抽象表达式类
变量解析器
运算符号解析器
加法解析器
减法解析器
测试
基本介绍:
1) Context 类为环境角色, 用于维护 State 实例,这个实例定义当前状态
2) State 是抽象状态角色,定义一个接口封装与 Context 的一个特点接口相关行为
3) ConcreteState 具体的状态角色,每个子类实现一个与 Context 的一个状态相关行为
Context类
环境角色具有两个职责,即处理本状态必须完成的任务,及决定是否可以过渡到其它状态。对于环境角色,有几个不成文的约束:
State抽象类
抽象环境中声明一个环境角色,提供各个状态类自行访问,并且提供所有状态的抽象行为,由各个实现类实现。
具体状态
测试
注意细节:
1) 代码有很强的可读性。状态模式将每个状态的行为封装到对应的一个类中。
2) 方便维护。将容易产生问题的 if-else 语句删除了,如果把每个状态的行为都放到一个类中,每次调用方法时都要判断当前是什么状态,不但会产出很多 if-else 语句,而且容易出错。
3) 符合“开闭原则”。容易增删状态。
4) 会产生很多类。每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护难度。
5) 应用场景:当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候, 可以考虑使用状态模式。
基本介绍:
Context:上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
Strategy :抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性
ConcreteStrategy:用于实现抽象策略中的操作,即实现具体的算法,不同策略不同类。
Context类(上下文角色)
Strategy抽象类(策略角色)
具体策略角色
测试
策略模式的应用:
抽象鸭子类
飞的接口
实现会飞的接口行为
实现不会飞的接口行为
实现的鸭子类(会飞)
实现的鸭子类(玩具鸭,不会飞,不会游泳)
客户端测试
注意细节:
1) 策略模式的关键是:分析项目中变化部分与不变部分
2) 策略模式的核心思想是:多用组合/聚合 少用继承;用行为类组合,而不是行为的继承。更有弹性
3) 体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为) 即可,避免了使用多重转移语句(if..else if..else)
4) 提供了可以替换继承关系的办法: 策略模式将算法封装在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易于切换、易于理解、易于扩展
5) 需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞
基本介绍:
类图
1) Handler : 抽象的处理者, 定义了一个处理请求的接口, 同时含义另外 Handler
2) ConcreteHandlerA , B 是具体的处理者, 处理它自己负责的请求, 可以访问它的后继者(即下一个处理者), 如果可以处理当前请求,则处理,否则就将该请求交个 后继者去处理,从而形成一个职责链
3) Request , 含义很多属性,表示一个请求
具体例子:
客户请求类
抽象处理者
具体处理者
测试
注意细节:
1) 将请求和处理分开,实现解耦,提高系统的灵活性
2) 简化了对象,使对象不需要知道链的结构
3) 性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在 Handler 中设置一个最大节点数量,在 setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
4) 调试不方便。采用了类似递归的方式,调试时逻辑可能比较复杂