【地铁上的设计模式】--结构型模式:代理模式

2023-05-07 21:26:52 浏览数 (1)

什么是代理模式

代理模式是一种结构型设计模式,通过代理对象控制对原始对象的访问。代理对象充当客户端和实际对象之间的中介,隐藏了实际对象的复杂性,并提供了一些额外的控制。

在软件系统中,代理模式可以有多种应用。例如,代理模式可以用于实现远程代理、虚拟代理、保护代理和智能代理等。

远程代理是指代理对象用于在不同的地址空间中代表实际对象。虚拟代理是指代理对象在访问实际对象时先加载一些开销较小的信息,等到需要时再加载开销较大的信息。保护代理是指代理对象控制对实际对象的访问,以保护实际对象不被意外修改。智能代理是指代理对象在访问实际对象时,提供额外的服务,如缓存、日志、事务等。

代理模式有三个关键角色:抽象主题、实际主题和代理。抽象主题定义了实际主题和代理的公共接口。实际主题是实际要被代理的对象。代理对象持有实际主题的引用,并且可以在客户端请求时代理实际主题的访问。 代理模式的优点包括:

  1. 对客户端透明:客户端不需要知道实际主题的存在,而是通过代理对象访问实际主题。
  2. 减少系统开销:代理模式可以延迟实际主题的创建和加载,从而减少系统的开销。
  3. 提高系统可扩展性:通过使用代理模式,可以轻松地添加新的代理和实际主题,而不需要修改现有的代码。

代理模式的缺点包括:

  1. 增加系统复杂性:在设计时,需要考虑代理对象和实际对象之间的关系,这会增加系统的复杂性。
  2. 降低系统性能:由于代理模式需要额外的处理过程,可能会降低系统的性能。
  3. 增加代码量:代理模式需要编写额外的代码来实现代理对象和实际对象之间的交互,从而增加代码量。
如何实现代理模式

实现代理模式的步骤如下:

  1. 定义一个接口或抽象类,声明业务方法;
  2. 实现业务类,实现业务接口或抽象类;
  3. 实现代理类,代理类中包含对业务类的引用,并实现业务接口或抽象类;
  4. 在代理类中实现业务方法时,通过业务类对象的引用调用业务方法;
  5. 客户端只和代理类打交道,通过代理类间接访问业务类,实现对业务类的访问控制和增强。

通过代理模式,我们可以在不改变业务类的前提下,对业务方法进行访问控制和增强。代理模式可以分为静态代理和动态代理两种,其中静态代理需要编写代理类,而动态代理则是在运行时动态生成代理类,相对来说更加灵活。

Java实现 以下是Java实现代理模式的示例代码:

代码语言:javascript复制
// 定义一个接口
public interface Subject {
    void doSomething();
}

// 被代理类
public class RealSubject implements Subject {
    public void doSomething() {
        // 实现具体的业务逻辑
    }
}

// 代理类
public class ProxySubject implements Subject {
    private RealSubject realSubject;
    
    public void doSomething() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        // 执行额外的操作,如权限控制、性能统计等
        realSubject.doSomething();
    }
}

在上面的代码中,Subject是被代理类和代理类的共同接口,RealSubject是被代理类,ProxySubject是代理类。在ProxySubjectdoSomething()方法中,会在调用被代理类的方法之前,执行一些额外的操作,比如权限控制、性能统计等。需要注意的是,代理类和被代理类要实现相同的接口,以便能够在客户端中互换使用。 需要使用代理模式的时候,只需要将实际的业务逻辑放在被代理类中实现,然后在代理类中引用被代理类,并在调用被代理类的方法之前添加一些额外的操作即可。

C#实现 以下是C#中实现代理模式的示例代码:

代码语言:javascript复制
// 定义一个共同的接口
public interface ISubject
{
    void Request();
}

// 定义实际主题
public class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("RealSubject.Request() is called.");
    }
}

// 定义代理
public class Proxy : ISubject
{
    private ISubject subject;

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

    public void Request()
    {
        if (subject == null)
        {
            subject = new RealSubject();
        }

        Console.WriteLine("Proxy.Request() is called before RealSubject.Request().");
        subject.Request();
        Console.WriteLine("Proxy.Request() is called after RealSubject.Request().");
    }
}

// 客户端
class Client
{
    static void Main(string[] args)
    {
        ISubject proxy = new Proxy(null);
        proxy.Request();
    }
}

在以上示例代码中,我们定义了一个共同的接口 ISubject,包含了代理和实际主题都必须实现的 Request() 方法。接着,我们定义了实际主题类 RealSubject 和代理类 Proxy,并在代理类中持有了一个实际主题对象。 在代理类的 Request() 方法中,我们可以进行一些预处理,然后调用实际主题的 Request() 方法,并在调用结束后进行一些后续处理。这里我们使用了一个简单的判断,如果实际主题对象还没有被创建,就先创建一个实际主题对象。最后,在客户端中,我们实例化了一个代理对象,并调用了 Request() 方法。

总结

代理模式是一种结构型设计模式,它允许创建一个代理对象作为其他对象的接口。代理模式提供了一种中介机制,通过这种机制,代理对象可以控制访问其他对象的方式,并提供额外的功能。 代理模式的优点在于它可以降低系统中组件的耦合度,通过使用代理对象,客户端可以在不直接访问目标对象的情况下访问其方法。这有助于实现系统中的分层设计,保护目标对象免受不必要的访问,提高系统的安全性和可维护性。 另一个优点是代理对象可以提供额外的功能,比如在访问目标对象之前或之后执行某些操作,这样就可以在不影响目标对象的情况下实现对目标对象的定制化扩展。 然而,代理模式也有一些缺点,比如增加了系统中的额外代码量,导致了系统的复杂性增加。此外,代理对象还可能导致系统性能的下降,因为它需要在访问目标对象之前或之后执行额外的操作。 因此,在使用代理模式时,需要仔细权衡其优缺点,并选择适合自己应用场景的实现方式。

0 人点赞