0305 - 设计模式
2021-05-12 23:03:21 0 举报
AI智能生成
系统架构、Java技术栈、面试宝典
作者其他创作
大纲/内容
单例模式
饿汉方式
懒汉方式
双重检测机制
单例注册表方式
工程模式
应用场景
Spring创建Bean
代理模式
应用场景
Motan服务的动态代理
分类
静态代理
编译的时就已经创建好了代理类
动态代理
JDK动态代理
CGLIB
Javassist
构造者模式
应用场景
PB序列化中的Builder
责任链模式<br>
应用场景
Netty消息处理的方式
适配器模式
应用场景
SLF4J如何支持Log4j
观察者模式
应用场景
GRPC是如何支持流式的请求
其它模式
设计模式
创建型6种
单例模式(Singleton)<br>
懒汉式
饿汉式
<br>
懒汉式(双重检测)
静态内部类
枚举类<br>
工厂模式(Factory)
简单工厂模式
子主题
工厂方法模式
具体工厂生产具体的产品,在简单工厂基础上增加了“抽象工厂”角色
抽象工厂模式
包含创建一族产品的工厂方法,每个方法对应一个产品族
建造者模式(Builder)
原型模式(Prototype)
背景
与其它创建型模式不同,原型模式不是在他们的基础上的改进
概念
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。本质: 通过一个原始对象为模版,克隆出更多一模一样的对象;<br>在java中就是clone方法;
目的
提高效率、绕过构造方法、使用方便
优缺点
优点:<br>--高性能<br>通过new进行创建对象时,需要首先获取class信息,计算出所需内存大小,分配内存,赋默认值,执行代码块、执行构造方法初始化 等一系列动作;<br>而使用clone方法,只需要根据原始对象大小分配内存,然后复制二进制流即可;省去了很多的计算和初始动作;因此性能会较高;<br>--绕过构造方法<br>这个即是优点,某些情况下可能也是缺点;<br>如果一个对象的初始化非常消耗性能,比如:通过加载数据库配置,则绕过构造方法会大大提高性能;<br>--使用简单<br>这也是创建型模式的基本优点,它隐藏了对象创建的内部细节;<br>最核心的目的:高性能、方便、快速的创建出大量一模一样的对象<br>-----------------------------------------------------------------------------------------------------------------------------------------------------------<br>缺点:<br>--绕过构造方法<br>--一些必须通过构造方法进行不同初始化的操作将无法执行;<br>
现时案例
jdk 中的cloneable接口
对象克隆
深克隆
是指复制的两个对象本身及对象的属性(包括所有递归属性)都是完全全新的对象;在内存是,是两块不同的内存块;
浅克隆
是指复制的两个对象本身是不同的,但是属性值引用的是同一个对象;即拷贝的是同一个同象的引用;
结构型7种
适配器模式(Adapter)
对象适配器
适配器与适配者之间是关联关系
类适配器
适配器与适配者之间是继承(或实现)关系
双向适配器
在适配器中同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法
缺省适配器
在不需要实现接口中所有方法时,可以使用一个抽象类去实现该接口,并提供其中方法的默认实现
在一些开源框架中应用广泛:如Spring MVC中典型的HandlerInterceptor接口和HandlerInterceptorAdapter抽象类
代理模式(Proxy)
场景
假如你是一个业主,有一套500万的房子需要出售;你希望找一个合适的客户,签个合同,收了钱,然后把房子过户给客户就可以了;<br>但是,有太多的客户天天找你需要看房,询问,而且大部分都是没有诚意的客户,让你不胜其烦;<br>业主: 只需要签字收钱就好了,剩下的事情,如果有人能帮我处理就发了;<br>
图形化展示
概念
为其他对象提供一种代理以控制对这个对象的访问;<br>本质: 引入一个中介类, 这个类实现了被代理类相同的接口或继承自被代理类,对外假装成被代理对象,帮被代理对象处理一些非必要或不能做的事情;但核心功能,仍然通过调用被代理对象来实现;
目的
不修改原来代码的情况下,动态地给一个对象添加一些额外的职责和功能,或者添加一些控制功能,以限制对原对象的访问<br>本质:动态增加功能;把需要新增加的功能以代理的方式动态的添加到原对象上;
优缺点
优点:<br>--松耦合<br>在不修改原来代码的情况下,动态的为原类增加新功能<br>--扩展性高<br>只需要增加新的代理功能类,就可以对原类不断增加新功能<br>--灵活<br>通过动态代理,不修改调用方和被调用方的情况下动态增加新功能<br>----------------------------------------------------------------------------------------------<br>缺点:<br>--代理实现起来可能会比较复杂<br>--增加了中介类,可能会对性能有影响<br>----------------------------------------------------------------------------------------------<br>最核心的目的:在不修改原代码的情况下,动态的为对象增加或减少某些功能,以及控制对被代理类的访问<br>
应用场景
A、远程代理<br>B、虚拟代理<br>C、Copy-on-Write 代理<br>D、保护(Protect or Access)代理<br>E、Cache代理<br>F、防火墙(Firewall)代理<br>G、同步化(Synchronization)代理<br>H、智能引用(Smart Reference)代理 <br>
现实案例
spring @Aspect aop对应的实现
应用分类
JDK代理
静态代理
让代理类和目标类实现一样的接口,同时代理类中维护一个目标类对象的引用
动态代理
它是静态代理的改进,当代理接口发生改变时相应的代理对象也随之改变,让代理类实现InvocationHandler接口,动态为目标接口生成代理类
缺点:目标类必须实现接口
cglib代理
使用字节码技术(asm框架)动态创建目标类的子类作为代理类,突破了JDK代理目标类必须实现接口的限制
缺点:无法为final修饰的类或方法创建代理
装饰模式(Decorator)
背景
某些情况,当一个类已经存在,并且可以对外提供核心功能时,但是,某个时刻,希望对这个类进行功能增强(如:增加缓存);通常情况,我们可以修改原来的类,并增加对应的增强功能即可;<br>但是,这种方式违背了“开-闭”原则,需要修改原来的代码;而且不够灵活,如果有某个时刻又不想使用缓存,又需要修改原来的代码,显然,这不是一个很好的解决方案;<br>
概念
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。<br>本质: 引入一个中介类,这个类实现了被装饰者相同的接口,对外假装成被装饰者,并通过引用被装饰者,在调用被装饰者前后做一些附加功能(如:缓存,参数预处理);
目的
不修改原来代码的情况下,动态地给一个对象添加一些额外的职责和功能<br>本质:动态增加功能;把需要新增加的功能预先制作成零件,在需要时“动态“的添加到对象上;<br>
优缺点
优点:<br>--松耦合<br>在不修改原来代码的情况下,动态的为原类增加新功能<br>--扩展性高<br>只需要增加新的装饰类,就可以对原类不断增加新功能<br>--灵活<br>不需要通过继承来扩展,而且可以动态增加或去除新装饰类,从而随意对原对象增加或减少某些功能<br>-----------------------------------------------------------------------------------------<br>缺点:<br>--额外引入第三方<br>-----------------------------------------------------------------------------------------<br>最核心的目的:在不修改原代码的情况下,动态的为对象增加或减少某些功能<br>
应用场景
扩展类的功能时<br>动态增加或取消某些功能时
现实案例
JDK中的流处理;<br>ByteArrayInputStream<br>FileInputStream<br>ObjectInputStream <br>PipedInputStream
外观/门面模式(Facade)<br>
背景
我是一个辛苦一辈子的农民,攒了几十年钱,现在日子好了,也想建一套属于自己的小洋楼;首先,我要雇一个搬砖的和一个和泥的,还要一个会砌墙的人;可是我到哪里去找这些人,还要一个一个跟他们谈价钱;不知道他们和不和得来,会不会干一半不干了;哎,好烦;要是有一个人什么都会就好,我只要跟他谈,他一个人就能帮我把房子建好;<br>
图形化展示
概念
提供一个统一的接口去访问多个子系统的多个不同的接口,它为子系统中的一组接口提供一个统一的高层接口。使用子系统更容易使用。本质:就是化零为整;引入一个中介类,把各个分散的功能组合成一个整体,只对外暴露一个统一的接口;
目的
为了用户使用方便,把过度拆分的分散功能,组合成一个整体,对外提供一个统一的接口
优缺点
优点:<br>--松耦合<br>用户与子系统解耦,屏蔽子系统;可以提高子系统的独立性;<br>--使用简单<br>简化用户与子系统的依赖关系;<br>用户只与门面对接,有统一的入口;不需要知道所有子系统及内部构造;<br>----------------------------------------------------------------------------------<br>缺点:<br>不规范的编程方式<br>没有面向抽象编程,而是通过增加中介层,转换服务提供方的服务接口; <br>
使用场景
A:简化子系统复杂性时。<br>B:监控所有子系统时;通过门面控制了入口,可以统一监控;<br>C:希望封装和隐藏子系统时;<br>D:两历史系统进行改造并打通关系时;
实现案例
spring ApplicationContext;<br>它实现了Factory、ResourceLoader等接口,并通过引用这些接口的实例,对外统一提供:加载配置、解析资源、创建Bean、提供环境、启动流程等功能;<br>客户代码只需要操作context就可以获取spring的提供的功能,而无需关心内部的细节;<br>
桥接模式(Bridge)
组合模式(Composite)
享元模式(Flyweight)
行为型11种
观察者模式(Observer)
模板方法模式(Template)
策略模式(Strategy)
迭代器模式(Iterator)
责任链模式(Chain of Responsibility)
命令模式(Command)
状态模式(State)
访问者模式(Visitor )
中介者模式(Mediator)
备忘录模式 (Memento )
解释器模式(Interpreter)
0 条评论
下一页