工厂模式
解释: (这种说法存在疑问: 因为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();
这段代码有代码的入侵, 可以考虑使用动态代理来减少代码的侵入, 降低
耦合度;
以上内容只是一个大概的目录, 后续会继续修改;