设计模式笔记

工厂模式

解释: (这种说法存在疑问: 因为abs抽象类可以直接去掉, 等到后面看spring源码的时候在说), 快速创建同一个类的不同的实现的, 并隐藏该类的创建过程, 直接获取, 随着类的越来越多, 分类的越来越复杂, 工厂开始专业化, 因此出现了工厂的分类, 因此出现了工厂的分类, 抽象工厂模式

abstractFactory {
    getA()
    getB()
    getC()
}
factory extends abstractFactory {
    getA(){...}
    getB(){...}
    getC(){...}
}

这里使用抽象类的主要原因是, 抽象类中可以实现一些公共的逻辑, 又
可以添加继承类必须要实现的方法, 这种模式是在spring中使用的最多的;

单例模式

主要是保证在项目中只有一个实例, 保证线程的安全, 同时系统节省开销.

饿汉式

不论用不用都先new出来, 这种的可以保证线程安全, 但是增加系统开销
但是使用序列化和反序列化的时候, 还是可以获取到两个实例, 可以在类中添加

readResolve() {
    return a;
}

方法来避免;

class A {
    private A () {}
    private static final A a = new A()
    public static A getInstance() {
    return a;
}

}
懒汉式

用的时候在new, 会存在线程安全问题, 和指令重排序问题

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). 或者使用静态内部类: 主要是因为静态内部类不论外部类被加载
多少次, 他只加载一次(可以使用反射来多次获取)

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). 普通的代理模式(缺点, 只能帮有限的对象进行代理, 存在局限性)

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

这段代码有代码的入侵, 可以考虑使用动态代理来减少代码的侵入, 降低
耦合度;

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

你可能感兴趣的:(设计模式)