设计模式笔记

工厂模式

解释: (这种说法存在疑问: 由于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代理

代理模式(spring实现AOP的主要方法)

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();

这段代码有代码的入侵, 能够考虑使用动态代理来减小代码的侵入, 下降
耦合度;

以上内容只是一个大概的目录, 后续会继续修改;