1287 2018-03-18 2020-06-25
前言:站在巨人的肩膀上,学习设计模式。
一、概述
结构型模式(Creational Patterns)主要用于处理类或对象的组合,GoF提供了7种结构型模式,分别是
- 适配器模式(Adapter)
- 桥接模式(Bridge)
- 组合模式(Composite)
- 装饰模式(Decorator)
- 外观模式(Facade)
- 享元模式(Flyweight)
- 代理模式(Proxy)
二、适配器模式
1、概述
定义:将一个类的接口转换成用户希望的另一个接口,使得原本由于接口不兼容而不能工作的那些类可以一起工作。
说明:使原本不兼容的事物能够协同工作,而无须修改现有事物的内部结构。
2、类图
3、默认适配器
三、桥接模式
1、概述
定义:将抽象部分与实现部分分离,使它们都可以独立地变化。
说明:当事物存在两个独立变化的维度时,将两个变化因素抽取出来形成高层次的关联关系,使原本复杂的类继承结构变得相对简单,极大减少系统中类的个数。
桥接模式是我非常喜欢的一种模式。
2、类图
四、组合模式
定义:将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。
说明:通过面向对象技术来实现对系统中存在的容器对象和叶子对象进行统一操作,且客户端无须知道操作对象是容器还是其成员。比如JDK中的File类。
五、装饰模式
1、概述
定义:动态地给一个对象添加一些额外的职责,就扩展功能而言,它比生成子类方式更为灵活。
说明:不使用继承而通过关联关系来调用现有类中的方法,达到复用的目的,并使得对象的行为看可以灵活变化。
装饰模式也是我非常喜欢的一种模式。
2、标准类图
3、简化版类图
六、外观模式
定义:为子系统的一组接口提供一个一致的界面,定义一个高层接口,这个接口使得这一子系统更加容易使用。
说明:为复杂的子系统提供一个统一的入口,简化客户端对多个子系统的访问。类似于面向对象里面的封装,提供外部调用,而无须关心内部逻辑。
七、享元模式
定义:运用共享技术有效支持大量细粒度的对象。
说明:通过共享技术实现对象的重用,大量节约系统的内存,该模式关心系统的性能与资源利用情况。比如缓存技术、JDK中的String类。
八、代理模式
1、概述
定义:为其他对象提供一个代理以控制这个对象的访问。
说明:当不能直接访问一个对象时,通过一个代理对象间接访问它。
2、类图
3、动态代理
动态代理是一种较为高级的代理模式,它的典型应用就是Spring AOP。下面是一个简单的例子
public class Client {
interface AbstractSubject {
void request();
}
static class RealSubjectA implements AbstractSubject {
@Override
public void request() {
System.out.println("真实主题类A");
}
}
static class RealSubjectB implements AbstractSubject {
@Override
public void request() {
System.out.println("真实主题类B");
}
}
// 使用JDK代理,代理类必须实现某个接口,CGLIB代理是继承代理类
static class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
/**
* @param proxy 代理类
* @param method 需要代理的方法
* @param args 代理方法的参数数组
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
preRequest();
Object obj = method.invoke(object, args);
postRequest();
return obj;
}
private void preRequest() {
System.out.println("调用之前");
}
private void postRequest() {
System.out.println("调用之后");
}
}
public static void main(String[] args) {
InvocationHandler handler = new DynamicProxy(new RealSubjectA());
// newProxyInstance参数依次为:代理类的类加载器,代理类实现的接口列表,所指派的调用处理类
AbstractSubject subject = (AbstractSubject) Proxy.newProxyInstance(AbstractSubject.class.getClassLoader(), new Class[]{AbstractSubject.class}, handler);
subject.request();
System.out.println("--------------------------");
handler = new DynamicProxy(new RealSubjectB());
subject = (AbstractSubject) Proxy.newProxyInstance(AbstractSubject.class.getClassLoader(), new Class[]{AbstractSubject.class}, handler);
subject.request();
}
}
下面为输出结果:
调用之前
真实主题类A
调用之后
--------------------------
调用之前
真实主题类B
调用之后
总访问次数: 368次, 一般般帅 创建于 2018-03-18, 最后更新于 2020-06-25
欢迎关注微信公众号,第一时间掌握最新动态!