常见设计模式的原理、应用场景总结——结构型

本文总结了结构型设计模式,包括代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式和享元模式。代理模式常用于控制访问和增加非功能性需求;桥接模式实现抽象与实现的解耦;装饰器模式用于给对象添加功能,减少继承关系;适配器模式解决接口不兼容问题;门面模式提供高层次接口;组合模式处理树形结构数据;享元模式用于对象复用,节省内存。
摘要由CSDN通过智能技术生成

结构型设计模式

在这里插入图片描述
常见设计模式的原理、应用场景总结——创建型

结构型模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决特定应用场景的问题。结构型模式包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式。

1.代理模式

代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问, 而非加强功能,这是它跟装饰器模式最大的不同。一般情况下,我们让代理类和原始类实现同样的接口。但是,如果原始类并没有定义接口,并且原始类代码并不是我们开发维护的。 在这种情况下,我们可以通过让代理类继承原始类的方法来实现代理模式。
静态代理需要针对每个类都创建一个代理类,并且每个代理类中的代码都有点像模板式的“重复”代码,增加了维护成本和开发成本。对于静态代理存在的问题,我们可以通过动态代理来解决。我们不事先为每个原始类编写代理类,而是在运行的时候动态地创建原始类对应的代理类,然后在系统中用代理类替换掉原始类。代理模式常用在业务系统中开发一些非功能性需求,比如:监控、统计、鉴权、限流、事务、幂等、日志。我们将这些附加功能与业务功能解耦,放到代理类统一处理,让程序员只需要关注业务方面的开发。除此之外,代理模式还可以用在 RPC、缓存等应用场景中。

示例

/**
 * 所谓动态代理(Dynamic Proxy),就是我们不事先为每个原始类编写代理类,而是在运行的时候,动态地创建原始类对应的代理类,然后在系统中用代理类替换掉原始类。
 * 可以看到这里没有跟业务相关的类
 */
public class MetricsCollectorProxy {
   
    private MetricsCollector metricsCollector;

    public MetricsCollectorProxy() {
   
        this.metricsCollector = new MetricsCollector();
    }

    public Object createProxy(Object proxiedObject) {
   
        Class<?>[] interfaces = proxiedObject.getClass().getInterfaces();
        DynamicProxyHandler handler = new DynamicProxyHandler(proxiedObject);
        return Proxy.newProxyInstance(proxiedObject.getClass().getClassLoader(), interfaces, handler);
    }

    private class DynamicProxyHandler implements InvocationHandler {
   
        private Object proxiedObject;

        public DynamicProxyHandler(Object proxiedObject) {
   
            this.proxiedObject = proxiedObject;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   
            long startTimestamp = System.currentTimeMillis();
            Object result = method.invoke(proxiedObject, args);
            long endTimeStamp = System.currentTimeMillis();
            long responseTime = endTimeStamp - startTimestamp;
            String apiName = proxiedObject.getClass().getName() + ":" + method.getName();
            RequestInfo requestInfo = new RequestInfo(apiName, responseTime, startTimestamp);
            metricsCollector.recordRequest(requestInfo);
            return result;
        }
    }
    
	public static void main(String[] args) {
   
	        MetricsCollectorProxy proxy = new MetricsCollectorProxy();
	        //jdk动态代理的原始类必须要实现一个接口
	        IUserController userController = (IUserController) proxy.createProxy(new UserController());
	        userController.login("13607841111", "123456");
	    }
}
2. 桥接模式

桥接模式的代码实现非常简单,但是理解起来稍微有点难度,并且应用场景也比较局限࿰

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值