代理模式是一种结构型模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在将请求提交给对象前后进行一些处理。
为什么要控制对于某个对象的访问呢?举个例子:有这样一个消耗大量系统资源的巨型对象,你只是偶尔需要使用它,并非总是需要。
你可以实现延迟初始化:在实际有需要时再创建该对象。对象的所有客户端都要执行延迟初始代码。不幸的是,这很可能会带来很多重复代码。
在理想情况下,我们希望将代码直接放入对象的类中,但这并非总是能实现:比如类可能是第三方封闭库的一部分。
代理模式建议新建一个与原服务对象接口相同的代理类,然后更新应用以将代理对象传递给所有原始对象客户端。代理类接收到客户端请求后会创建实际的服务对象,并将所有工作委派给它。
这有什么好处呢?如果需要在类的主要业务逻辑前后执行一些工作,你无需修改类就能完成这项工作。由于代理实现的接口与原类相同,因此你可将其传递给任何一个使用实际服务对象的客户端。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 | using System;namespace RefactoringGuru.DesignPatterns.Proxy.Conceptual{ // The Subject interface declares common operations for both RealSubject and // the Proxy. As long as the client works with RealSubject using this // interface, you'll be able to pass it a proxy instead of a real subject. public interface ISubject { void Request(); } // The RealSubject contains some core business logic. Usually, RealSubjects // are capable of doing some useful work which may also be very slow or // sensitive - e.g. correcting input data. A Proxy can solve these issues // without any changes to the RealSubject's code. class RealSubject : ISubject { public void Request() { Console.WriteLine("RealSubject: Handling Request."); } } // The Proxy has an interface identical to the RealSubject. class Proxy : ISubject { private RealSubject _realSubject; public Proxy(RealSubject realSubject) { this._realSubject = realSubject; } // The most common applications of the Proxy pattern are lazy loading, // caching, controlling the access, logging, etc. A Proxy can perform // one of these things and then, depending on the result, pass the // execution to the same method in a linked RealSubject object. public void Request() { if (this.CheckAccess()) { this._realSubject.Request(); this.LogAccess(); } } public bool CheckAccess() { // Some real checks should go here. Console.WriteLine("Proxy: Checking access prior to firing a real request."); return true; } public void LogAccess() { Console.WriteLine("Proxy: Logging the time of request."); } } public class Client { // The client code is supposed to work with all objects (both subjects // and proxies) via the Subject interface in order to support both real // subjects and proxies. In real life, however, clients mostly work with // their real subjects directly. In this case, to implement the pattern // more easily, you can extend your proxy from the real subject's class. public void ClientCode(ISubject subject) { // ... subject.Request(); // ... } } class Program { static void Main(string[] args) { Client client = new Client(); Console.WriteLine("Client: Executing the client code with a real subject:"); RealSubject realSubject = new RealSubject(); client.ClientCode(realSubject); Console.WriteLine(); Console.WriteLine("Client: Executing the same client code with a proxy:"); Proxy proxy = new Proxy(realSubject); client.ClientCode(proxy); } }} |
---|
执行结果:
1234567 | Client: Executing the client code with a real subject:RealSubject: Handling Request.Client: Executing the same client code with a proxy:Proxy: Checking access prior to firing a real request.RealSubject: Handling Request.Proxy: Logging the time of request. |
---|
参考原文:代理设计模式