先抓一张网上的类图:
代理模式:就是使用一个代理类,代替了真正的我们要使用的类。
从图中可以看出 代理类proxy, 真正要使用的的类RealSubject. 它们都是Subject的子类
使用了代理类的主要目的:
一. 为了解耦。client使用的是代理类,而不是RealSubject, 业务代码与非业务代码也实现了分离.
二. 通过代理类,我们对realsubject的业务可以进行封装和扩充,增加额外的业务处理,如,请求过滤,增加日志,权限等。我觉得这才是代理的核心作用
代理模块的实现,有静态代理和动态代理两种。
静态代理:如类图所示:一个真实对象,需要创建一个对应的代理对象,这样无疑增加了类的数量,增加了复杂度。
动态代理:通过反射等技术手段,动态增加代理类。
先来看下静态代理的代码如下:
/// <summary> /// 酒店服务 /// </summary> public interface IHotelService { /// <summary> /// 客房预订 /// </summary> void Booking(); } public class HotelService : IHotelService { public void Booking() { // 业务逻辑。。。 } } /// <summary> /// Ctrip携程,第三方 /// </summary> public class CtripService : IHotelService { private HotelService hotelService; public CtripService() { hotelService = new HotelService(); } public void Booking() { // Before 租车 + 早餐 + 保险 hotelService.Booking(); // After 景点门票+其他费用 } } public class Customer { public void Travel() { IHotelService hotelService = new CtripService(); // 使用代理模式,如使用第三方的服务,势必要加一些其他的“服务”项目。。。。。 hotelService.Booking(); } }
再来看一下动态代理的代码,
这里我们直接使用Castle的动态代理:
/// <summary> /// 酒店服务 /// </summary> public interface IHotelService { /// <summary> /// 客房预订 /// </summary> void Booking(); } public class HotelService : IHotelService { //使用Castle动态代理,被代理的方法,需要加virtual public virtual void Booking() { // 业务逻辑。。。 } } public class CtripProcessCastle : IInterceptor { public void Intercept(IInvocation invocation) { this.Before(); invocation.Proceed(); this.After(); } public void Before() { //租车 + 早餐 + 保险 } public void After() { //景点门票+其他费用 } } public class Customer { public void Travel() { ProxyGenerator generator = new ProxyGenerator(); CtripProcessCastle castle = new CtripProcessCastle(); IHotelService proxy = generator.CreateClassProxy<HotelService>(castle); proxy.Booking(); } }
我们减少那个代理类,增加了一个类用于处理第三方业务逻辑的类(这个类是必不可少的,总要写一下要做什么)
代理模式的应用:
1. AOP编程:这一点从asp.net mvc的actionfilter可以明显的看出来
2. 延迟加载:new代理类的时候什么都不做,booking的时候,再new RealSubject. 意思就是说真正使用这个类的时候才new,避免资源浪费。