解释: (这种说法存在疑问: 由于abs抽象类能够直接去掉, 等到后面看spring源码的时候在说), 快速建立同一个类的不一样的实现的, 并隐藏该类的建立过程, 直接获取, 随着类的愈来愈多, 分类的愈来愈复杂, 工厂开始专业化, 所以出现了工厂的分类, 所以出现了工厂的分类, 抽象工厂模式java
abstractFactory { getA() getB() getC() }
factory extends abstractFactory { getA(){...} getB(){...} getC(){...} }
这里使用抽象类的主要缘由是, 抽象类中能够实现一些公共的逻辑, 又
能够添加继承类必需要实现的方法, 这种模式是在spring中使用的最多的;web
主要是保证在项目中只有一个实例, 保证线程的安全, 同时系统节省开销.spring
饿汉式
不论用不用都先new出来, 这种的能够保证线程安全, 可是增长系统开销
可是使用序列化和反序列化的时候, 仍是能够获取到两个实例, 能够在类中添加安全
readResolve() { return a; }
方法来避免;并发
class A { private A () {} private static final A a = new A() public static A getInstance() { return a; } }
懒汉式
用的时候在new, 会存在线程安全问题, 和指令重排序问题ide
class A { private V () {} private static final A a = null public static A getInstance() { if(a == null) { return new A(); } return a; } }
解决的方法:
a). 使用double check+volatile
b). 或者使用静态内部类: 主要是由于静态内部类不论外部类被加载
多少次, 他只加载一次(可使用反射来屡次获取)spa
class A { private V () {} public static A getInstance() { return B.a } private static class B { private static final A a = new A() } }
注册式单例
将对象向同一个容器中注册, 下次使用时直接从容器中获取, spring中使用的就是注册式单例, 须要使用currentHashMap();线程
深复制和浅复制问题
深复制可使用字节码来实现, readObject代理
a). 普通的代理模式(缺点, 只能帮有限的对象进行代理, 存在局限性)code
class son { findLove() }
class proxy { proxy() { son传入 } findLove() { ... son.findLove ... } }
b). jdk的动态代理
class son implement Person{ findLove() }
class Proxy implement InvocationHandler { Proxy () { 传入对象son } invoke(...) { ... method.invoke(son, args) ... } }
使用方法
Son son = new Son() Proxy proxy = new Proxy(son) Person person = (Person)Proxy.newProxyInstance(son.getClass.getClassLoader,son.getClass.getInterfaces,proxy) person.findLove()
实现的原理
就是使用从新生成类的字节码方法, 获取到被代理类的引用, 而后使用代理类, 从新生成字节码, 并在字节码中加入要实现的方法;
c). cjlib代理方法
public class Dao { public void update() { System.out.println("PeopleDao.update()"); } public void select() { System.out.println("PeopleDao.select()"); } }
public class DaoProxy implements MethodInterceptor { @Override public Object intercept(Object object, Method method, Object\[\] objects, MethodProxy proxy) throws Throwable { System.out.println("Before Method Invoke"); proxy.invokeSuper(object, objects); System.out.println("After Method Invoke"); return object; } }
使用方法
DaoProxy daoProxy = new DaoProxy(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Dao.class); enhancer.setCallback(daoProxy); Dao dao = (Dao)enhancer.create(); dao.update(); dao.select();
委派模式 : 是静态代理的一种特殊状况, Delegate和dispacher开头的是委派模式
实现方式
class ServletDispacher { //list中保存了须要被委派的对象 ArrayList<Handler> handlers = new ArrayList<>(); doDispacher () { //该方法中, 进行相关的逻辑判断, 来选择要让哪一个Handler来去执行这个任务 } class Handler { ... } }
java Web中的Servlet就是使用的这种模式来接受请求, 并发送给对应的controller去执行的相关请求;
能够想象成一种电源转化器, 主要是在不改变原有功能的基础上, 对当下的业务作兼容,实现的方法
class Login { login(){} }
class ThirdLogin extends Login{ webLogin () { //处理相关逻辑 super.login() } qqLogin () { //处理相关逻辑 super.login() } }
装饰者模式
和适配器模式优势相似, 装饰者模式应用最典型的是java的inputStream和outputStream,而和适配器模式根本区别就是, 不论新对象如何装饰, 他们的顶层都是实现了InputStream的接口, 并且在实现的时候, 能够覆盖原来的方法, 是方法功能更强大, 能够将装饰者模者模式理解成特别的适配器模式;
观察者模式
顾名思义: 就是一个观察者, 在监听一个主题, 当这个主题发生改变或者发出消息时, 将消息发送给已经订阅该主题的订阅者
class Subject { List observer ...; add(){} remove(){} advice() { //遍历observer //而后observer.update() } }
//具体的主题
class ConcreteSubject { dosomeThing () { ... super.advice() {} } }
interface Observer { update() }
具体的观察者
class ConcreteObserver implement Observer{ uodate () { ... } }
使用方法
Observer observer = new ConcreteObserver() Subject subject = new ConcreteSubject() subject.add(observer) subject.dosomeThing();
这段代码有代码的入侵, 能够考虑使用动态代理来减小代码的侵入, 下降
耦合度;
以上内容只是一个大概的目录, 后续会继续修改;