设计模式 静态代理与动态代理模式

代理(Proxy)设计模式简介:

提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法
举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子

设计模式  静态代理与动态代理模式

静态代理:

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.

 

    class Program
    {
        static void Main(string[] args)
        {
            Member member = new Member() { Id=1,Name="test member"};
            IMemberService baseMemberService = new MemberServiceImpl();

            //代理原有业务类
            MemberSerivceImplStaticProxy memberService = new MemberSerivceImplStaticProxy(baseMemberService);
            //遵守接口契约
            string result = memberService.Create(member);

            System.Console.WriteLine(result);
            System.Console.ReadKey();
        }
    }

    class Member {
        public int Id { get; set; }
        public String Name { get; set; }

        public override string ToString(){
            return string.Format("Member[Id={0},Name={1}]", this.Id, this.Name);
        }
    }

    interface IMemberService {
        string Create(Member member);
    }

    class MemberServiceImpl : IMemberService {
        public string Create(Member member){
            Console.WriteLine("create member:"+member);
            return "SUCCESS";
        }
    }

    class MemberSerivceImplStaticProxy {
        private IMemberService target;

        public MemberSerivceImplStaticProxy(IMemberService target) {
            this.target = target;
        }

        public string Create(Member member){
            before(member);
            string result= target.Create(member);
            after(member);

            return result;
        }

        private void before(Member member){
            Console.WriteLine("before " + member);
        }

        private void after(Member member){
            Console.WriteLine("after " + member);
        }
    }

 

动态代理:

动态代理有以下特点:
1.代理对象,不需要实现接口
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
3.动态代理也叫做:JDK代理,接口代理

 class Program
    {
        static void Main(string[] args)
        {
            Member member = new Member() { Id=1,Name="test member"};
            IMemberService baseMemberService = new MemberServiceImpl();
            
            //代理原有业务类
            IMemberService memberService = (IMemberService)new MemberServiceImplDynamicProxy(baseMemberService).GetTransparentProxy();
            //遵守接口契约
            string result = memberService.Create(member);

            System.Console.WriteLine(result);
            System.Console.ReadKey();
        }
    }

    class Member {
        public int Id { get; set; }
        public String Name { get; set; }

        public override string ToString(){
            return string.Format("Member[Id={0},Name={1}]", this.Id, this.Name);
        }
    }

    interface IMemberService {
        string Create(Member member);
    }

    class MemberServiceImpl : IMemberService {
        public string Create(Member member){
            Console.WriteLine("create member:"+member);
            return "SUCCESS";
        }
    }

    class MemberServiceImplDynamicProxy : System.Runtime.Remoting.Proxies.RealProxy {
        private IMemberService target;

        public MemberServiceImplDynamicProxy(IMemberService target) : base(typeof(IMemberService)){
            this.target = target;
        }

        public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg){
            System.Runtime.Remoting.Messaging.IMethodCallMessage callMessage = (System.Runtime.Remoting.Messaging.IMethodCallMessage)msg;
            Member member = callMessage.Args[0] as Member;

            before(member);
            object returnValue = callMessage.MethodBase.Invoke(this.target, callMessage.Args);
            after(member);

            return new System.Runtime.Remoting.Messaging.ReturnMessage(returnValue, new object[0], 0, null, callMessage);
        }

        private void before(Member member){
            Console.WriteLine("before " + member);
        }

        private void after(Member member){
            Console.WriteLine("after " + member);
        }
    }

 

 为了让动态代理类更通用,可以对其调整为如下:

 

 class DynamicProxyFactory : System.Runtime.Remoting.Proxies.RealProxy
    {
        private object target;

        public DynamicProxyFactory(object target, Type targetType)
            : base(targetType)
        {
            this.target = target;
        }

        public override System.Runtime.Remoting.Messaging.IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)
        {
            System.Runtime.Remoting.Messaging.IMethodCallMessage callMessage = (System.Runtime.Remoting.Messaging.IMethodCallMessage)msg;

            before(this.target);
            object returnValue = callMessage.MethodBase.Invoke(this.target, callMessage.Args);
            after(this.target);

            return new System.Runtime.Remoting.Messaging.ReturnMessage(returnValue, new object[0], 0, null, callMessage);
        }

        private void before(object member)
        {
            Console.WriteLine("before " + member);
        }

        private void after(object member)
        {
            Console.WriteLine("after " + member);
        }
    }

 

对应客户端调用时也要变,变为如下:

 

    class Program
    {
        static void Main(string[] args)
        {
            Member member = new Member() { Id = 1, Name = "test member" };
            IMemberService baseMemberService = new MemberServiceImpl();

            //代理原有业务类
            IMemberService memberService = (IMemberService)new DynamicProxyFactory(baseMemberService, typeof(IMemberService)).GetTransparentProxy();
            //遵守接口契约
            string result = memberService.Create(member);

            System.Console.WriteLine(result);
            System.Console.ReadKey();
        }
    }

 

 

 


 

基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
 

上一篇:Redis基本数据结构之ZSet


下一篇:深度探索C++对象模型 个人总结 第三章 Data语意学