设计模式-------------静态/动态代理模式(结构型设计模式)

简介: 本文详细介绍了代理模式,包括其定义、应用场景、UML类图、代码实现和实际例子,阐述了静态代理和动态代理的区别以及它们的优缺点,展示了如何通过代理模式来控制对目标对象的访问并增强其功能。

文章目录

  • 1、代理模式定义
  • 2、应用场景
  • 3、UML类图
  • 4、通用代码实现
  • 5、结果
  • 6、实际例子(静态代理)
  • 7、动态代理生成对象的步骤
  • 8、代理模式的优缺点
  • 9、静态代理和动态代理的区别

1、代理模式定义

为其他对象提供一种代理,控制对对这个对象的访问。(你去找租房子、不是直接找房东。而是通过中介所给你提供房东的信息、然后你再去找对应的房东)

2、应用场景

  • 租房中介
  • 婚姻介绍
  • 中介找工作(打工人通过中介去电子厂打螺丝)

3、UML类图

在这里插入图片描述

  • 抽象主题角色:声明真实主题和代理主题的共同接口方法
  • 真实主题角色:被代理类,代表的真实对象,负责执行系统的真正的逻辑业务对象
  • 代理主题角色:代理类,持有RealSubject的引用,完全具备对RealSubject的代理权

(代理中持有子类实现的父类引用,就可以调用子类的真实实现方法,而且还可以在调用该方法之前。做一些额外的事情。代码功能增强、和spirng中的aop切面有点象。比如你要结婚,婚礼的布置和婚后的收拾,交给代理类实现。你只需要去结婚就行。这个婚礼的布置和收拾就像代码功能增强)

4、通用代码实现

package com.zheng.demo4;

public class Client {

    public static void main(String[] args) {

        new Proxy(new RealSubject()).request();

    }


    //抽象主题角色
    interface ISubject {
        public void request();//要做的事情
    }

    //真实角色
    static public class RealSubject implements ISubject {

        @Override
        public void request() {
            System.out.println("我要结婚啦");
        }
    }


    //代理角色
    static class Proxy implements ISubject {
        ISubject subject;

        public Proxy(ISubject subject) {
            this.subject = subject;
        }

        @Override
        public void request() {
            before();
            subject.request();//调用真实对象的业务逻辑
            after();
        }

        //方法增强、结婚前干的事情
        public void before() {
            System.out.println("布置婚礼现场");
        }

        //结婚后干的事情
        public void after() {
            System.out.println("婚礼现场的清理");
        }

    }
}

5、结果

在这里插入图片描述

6、实际例子(静态代理)

年轻人被催婚、介绍对象
代码结构
在这里插入图片描述
一个是静态代理、一个是动态代理。有对静态代理的改进为动态代理。
抽象

package com.zheng.demo4;

public interface IPerson {
    void findLove();
}

具体的人

package com.zheng.demo4;

public class LiSi implements IPerson {
    @Override
    public void findLove() {
        System.out.println("李四提出结婚对象的要求");
    }
}

代理

package com.zheng.demo4;


public class LiSiFather implements IPerson {
    LiSi liSi;

    public LiSiFather(LiSi liSi) {
        this.liSi = liSi;
    }

    @Override
    public void findLove() {
        liSi.findLove();
        System.out.println("李四的老爹开始寻找");
        System.out.println("试着交往");

    }

}

客户端

package com.zheng.demo4;

public class TestClient {
    public static void main(String[] args) {
        new  PersonProxy(new LiSi()).findLove();
    }
}

结果
在这里插入图片描述

缺点:李四的老爹只能给李四找对象、不能给其他人找对象。

解决方法、使用动态代理、把代理类搞成一个中介、给谁都可以介绍。动态代理的底层一般不用实现,直接调用现成的API。

package com.zheng.demo4;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MeiPoProxy implements InvocationHandler {

    private IPerson target;


    public IPerson getInstance(IPerson target) {
        this.target = target;
        Class<?> clazz = target.getClass();
        return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object result = method.invoke(this.target, args);
        after();
        return result;
    }

    //方法增强
    public void before() {
        System.out.println("我是婚姻中介所、收到了你的对象要求");
    }

    //方法增强
    public void after() {
        System.out.println("交换资料、开始交往吧");
    }
}

客户端调用

package com.zheng.demo4;

public class TestClient {
    public static void main(String[] args) {
        new MeiPoProxy().getInstance(new LiSi()).findLove();
    }
}

结果:
在这里插入图片描述

调用代理类的newProxyInstance方法
在这里插入图片描述
进入这个方法可以看到生成一个实例对象
在这里插入图片描述

在这里插入图片描述

7、动态代理生成对象的步骤

  • 1、获取被代理对象的引用,并且获取它的所有接口,反射获取
  • 2、JDK动态代理类重新生成一个新的类,同时新的类要实现被代理类实现的所有接口
  • 3、动态生成java代码,新加的业务逻辑方法由一定的逻辑代码调用
  • 4、编译新生成的java代码.class 文件
  • 5、重新加载到JVM中运行。

8、代理模式的优缺点

优点:

  • 代理对象和真实对象分开
  • 降低系统耦合性,扩展性好
  • 保护目标对象
  • 增强目标对象功能

缺点:

  • 类的数量增加
  • 增加代理对象,导致处理请求变慢
  • 增加系统复杂度

9、静态代理和动态代理的区别

  • 静态代理只能通过手动完成,被代理类增加新的方法,代理类也需要同步增加,违背开闭原则
  • 动态代理采用在运行时动态生成代码,取消了对被代理类的扩展限制,遵循开闭原则
  • 动态代理对目标类的增强逻辑进行扩展,结合策略模式
相关文章
|
3月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
174 11
|
8天前
|
设计模式 Java 关系型数据库
设计模式:工厂方法模式(Factory Method)
工厂方法模式是一种创建型设计模式,通过将对象的创建延迟到子类实现解耦。其核心是抽象工厂声明工厂方法返回抽象产品,具体工厂重写该方法返回具体产品实例。适用于动态扩展产品类型、复杂创建逻辑和框架设计等场景,如日志记录器、数据库连接池等。优点包括符合开闭原则、解耦客户端与具体产品;缺点是可能增加类数量和复杂度。典型应用如Java集合框架、Spring BeanFactory等。
|
4月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
93 40
|
6月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
2月前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
66 19
|
2月前
|
设计模式 Java
「全网最细 + 实战源码案例」设计模式——生成器模式
生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象。它允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化细节。该模式特别适合构建具有多种配置的复杂对象。其结构包括抽象建造者、具体建造者、指挥者和产品角色。适用于需要创建复杂对象且对象由多个部分组成、构造过程需对外隐藏或分离表示与构造的场景。优点在于更好的控制、代码复用和解耦性;缺点是增加复杂性和不适合简单对象。实现时需定义建造者接口、具体建造者类、指挥者类及产品类。链式调用是常见应用方式之一。
64 12
|
2月前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
59 15
|
4月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
4月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式