• 也说AOP


    前言

    1.引言

    2.Aop概念

    3.Aop实践

    4.总结

    一、引言

    对于初入行的小白来讲,aop,ioc这两个程序设计思想总是傻傻分不清,不知道是个什么东东?别人再一谈各种框架更是云里雾里。。。博主今天带大家且先入个门,哈哈;)

    二、Aop概念

    AOP为Aspect Oriented Programming的缩写,译为:面向切面编程。通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

    三、Aop实践

    在开发中,相信大家都遇到过验证用户权限的事情,那是不是需要在每个界面上都要加个判断呢?假如通过验证,就执行某某业务逻辑,不通过,就跳转或者提示啊 怎么怎么样。。。

                  示图一

    从程序设计的角度来考虑,验证用户 这件事情我们是不是可以分离出去呢,因为都是相同的嘛,减少重复,也是在不修改源代码的情况下动态统一添加功能;另一个方面可以 让一个对象尽可能的多关注自己的业务逻辑。这对于建立一个松耦合、可复用、可扩展性的系统是非常有利的。

    下面介绍静态代理和动态代理实现AOP。(IL编织实现AOP这篇暂时先不介绍。。。)

    创建公用的Model类

        public class User
        {
             public int Age { get; set; }
             public string Name { get; set; }       
        }

    代理模式 实现静态代理

         //代理模式  实现静态代理
        class DecoratorAop
        {
            public static void Show()
            {
                User user = new User
                {
                    Age = 3,
                    Name = "Michael"
                };
                IUserProcesser processer = new UserProcesser();
                processer.RegUser(user);
                IUserProcesser userProcesser = new UserProcesserDecorator(processer);
                userProcesser.RegUser(user);
            }
            public interface IUserProcesser
            {
                void RegUser(User user);
            }
            public class UserProcesser : IUserProcesser
            {
                public void RegUser(User user)
                {
                    Console.WriteLine($"注册用户,年龄为{user.Age},姓名{user.Name}");
                }
            }
            public class UserProcesserDecorator : IUserProcesser
            {
                public IUserProcesser userProcesser;
    
                public UserProcesserDecorator(IUserProcesser processer)
                {
                    userProcesser = processer;
                }
                public void RegUser(User user)
                {
                    BeforeProcess();
                    Console.WriteLine($"注册用户,年龄为{user.Age},姓名{user.Name}");
                    AfterProcess();
                }
                public void BeforeProcess()
                {
                    Console.WriteLine("方法执行前");
                }
                public void AfterProcess()
                {
                    Console.WriteLine("方法执行后");
                }
            }
    
        }
         class Program
        {
            static void Main(string[] args)
            {
                DecoratorAop.Show();
                Console.ReadLine();
            }
        }
    View Code

    使用.NET Remoting/RealProxy 实现动态代理

         class ProxyAop
        {
            public static void Show()
            {
                User user = new User
                {
                    Age = 3,
                    Name = "Michael"
                };
                UserProcessor userProcessor = TransparentProxy.Create<UserProcessor>();
                userProcessor.RegUser(user);
    
            }
            /// <summary>
            /// 真实代理
            /// </summary>
            /// <typeparam name="T"></typeparam>
            public class MyRealProxy<T> : RealProxy
            {
                private T tTarget;
                public MyRealProxy(T target)
                    :base(typeof(T))
                {
                    tTarget = target;
                }
    
                public override IMessage Invoke(IMessage msg)
                {
                    BeforeProcess();
                    IMethodCallMessage methodCallMessage = (IMethodCallMessage)msg;
                    object returnValue= methodCallMessage.MethodBase.Invoke(this.tTarget, methodCallMessage.Args);
                    AfterProcess();
                    return new ReturnMessage(returnValue,new object[0],0,null, methodCallMessage);
                }
                public void BeforeProcess()
                {
                    Console.WriteLine("方法执行前");
                }
                public void AfterProcess()
                {
                    Console.WriteLine("方法执行后");
                }
            }
            /// <summary>
            /// 透明代理
            /// </summary>
            public static class TransparentProxy
            {
                public static T Create<T>()
                {
                    T instance=  Activator.CreateInstance<T>();
                    MyRealProxy<T> myRealProxy = new MyRealProxy<T>(instance);
                    T transparentProxy= (T)myRealProxy.GetTransparentProxy();
                    return transparentProxy;
                }
            }
            public interface IUserProcessor
            {
                void RegUser(User user);
            }
            public class UserProcessor :MarshalByRefObject, IUserProcessor
            {
                public void RegUser(User user)
                {
                    Console.WriteLine($"用户已注册,年龄{user.Age},姓名{user.Name}");
                }
            }
    
        }
        class Program
        {
            static void Main(string[] args)
            {
                ProxyAop.Show();
                Console.ReadLine();
            }
        }
    View Code

    使用CastleDynamicProxy 实现动态代理

        public class CastleProxyAop
        {
            public static void Show()
            {
                User user = new User
                {
                    Age = 3,
                    Name = "Michael"
                };
                ProxyGenerator proxyGenerator = new ProxyGenerator();
                MyInterceptor myInterceptor = new MyInterceptor();
                UserProcessor userProcessor= proxyGenerator.CreateClassProxy<UserProcessor>(myInterceptor);
                userProcessor.RegUser(user);
                userProcessor.GetID();
            }
            public interface IUserProcessor
            {
                 void RegUser(User user);
                void GetID();
            }
            public class UserProcessor : IUserProcessor
            {
                public virtual void RegUser(User user)
                {
                    Console.WriteLine($"用户已注册,年龄{user.Age},姓名{user.Name}");
                }
                public virtual void GetID()
                {
                    Console.WriteLine($"这是1");
                }
            }
            public class MyInterceptor : IInterceptor
            {
                public void Intercept(IInvocation invocation)
                {
                    PreProceed();
                    invocation.Proceed();
                    PostProceed();
                }
                public void PreProceed()
                {
                    Console.WriteLine($"方法执行前");
                }
                public void PostProceed()
                {
                    Console.WriteLine($"方法执行后");
                }
            }
    
        }
         class Program
        {
            static void Main(string[] args)
            {
                CastleProxyAop.Show();
                Console.ReadLine();
            }
        }
    View Code

    使用EntlibPLAB Unity实现动态代理

         public class UnityAop
        {
            public static void Show()
            {
                User user = new User
                {
                    Age = 3,
                    Name = "Michael"
                };
                IUnityContainer unityContainer = new UnityContainer(); //声明一个容器
                unityContainer.RegisterType<IUserProcessor, UserProcessor>(); //声明unityContainer并注册IUserProcessor
    
                unityContainer.AddNewExtension<Interception>().Configure<Interception>()
                    .SetInterceptorFor<IUserProcessor>(new InterfaceInterceptor());
                IUserProcessor userProcessor = unityContainer.Resolve<IUserProcessor>();
                userProcessor.RegUser(user);
            }
    
            #region //特性对应的行为
            public class UserHandler : ICallHandler
            {
                public int Order { get; set; }
    
                public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
                {
    
                    User user = input.Inputs[0] as User;
                    if(user.Age<1)
                    {
                        return input.CreateExceptionMethodReturn(new Exception("年龄小于1岁禁止入内")); 
                    }
                    Console.WriteLine($"参数检测无误");
                    IMethodReturn methodReturn = getNext()(input, getNext);
                    return methodReturn;
                }
            }
    
            public class LogHandler : ICallHandler
            {
                public int Order { get; set; }
    
                public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
                {
    
                    User user = input.Inputs[0] as User;
                    string message = $"年龄{user.Age},姓名{user.Name}";
                    Console.WriteLine($"日志已记录,message:{message},time:{DateTime.Now}");
                    return getNext()(input, getNext);
                }
            }
    
            public class ExceptionHandler : ICallHandler
            {
                public int Order { get; set; }
    
                public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
                {
                    IMethodReturn methodReturn = getNext()(input, getNext);
                    if(methodReturn.Exception==null)
                    {
                        Console.WriteLine("无异常");
                    }
                    else
                    {
                        Console.WriteLine($"异常:{methodReturn.Exception.Message}");
                    }
                    return methodReturn;
                }
            }
            #endregion
    
            #region //特性
            public class UserHandlerAttribute : HandlerAttribute
            {
                public override ICallHandler CreateHandler(IUnityContainer container)
                {
                    ICallHandler callHandler = new UserHandler { Order = this.Order };
                    return callHandler;
                }
            }
            public class LogHandlerAttribute : HandlerAttribute
            {
                public override ICallHandler CreateHandler(IUnityContainer container)
                {
                    return new LogHandler { Order = this.Order };
                }
            }
            public class ExceptionHandlerAttribute : HandlerAttribute
            {
                public override ICallHandler CreateHandler(IUnityContainer container)
                {
                    ICallHandler callHandler = new ExceptionHandler { Order = this.Order };
                    return callHandler;
                }
            }
            #endregion
    
            #region //业务
            [ExceptionHandlerAttribute(Order =3)]
            [LogHandlerAttribute(Order =2)]   
            [UserHandlerAttribute(Order =1)]
            public interface IUserProcessor
            {
                void RegUser(User user);
            }
            public class UserProcessor : IUserProcessor
            {
                public void RegUser(User user)
                {
                    Console.WriteLine($"用户已注册,年龄{user.Age},姓名{user.Name}");
                }
            }
            #endregion
        }
         class Program
        {
            static void Main(string[] args)
            {
                UnityAop.Show();
                Console.ReadLine();
            }
        }
    View Code

    四、总结

    AOP的优点:

    1.解耦,将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑中分离出去,当这些行为改变时不影响业务逻辑。

    2.将通用功能从业务逻辑中抽离出来,提高代码复用性,灵活性,可扩展性。

    AOP与OOP的区别:

    OOP讲究“一切皆为对象”,使用类将世间万事万物的状态和行为模块化,封装继承多态。

    AOP是将切面(Aspect)模块化。纵向切入,对业务处理过程中的切面进行提取,以获得逻辑过程中各部分之间低耦合的隔离效果,使应用对象更加关注业务逻辑,实现解耦,提供程序灵活性及可扩展性。

    适用场景:日志记录,性能统计,安全控制,事务处理,异常处理。

    参考:

    http://www.cnblogs.com/landeanfen/p/4782370.html

    http://www.cnblogs.com/jin-yuan/p/3811077.html

    http://wayfarer.cnblogs.com/articles/241024.html

  • 相关阅读:
    非易失性存储器EEPROM
    NAND FLASH系统的权衡利弊
    Python爬虫爬取爱奇艺电影片库首页
    xpath解析爱奇艺电影网页数据
    BeautifulSoup 库 和 re 库 解析腾讯视频电影
    《人月神话》读书笔记(一)
    Python爬取腾讯视频电影名称和链接(一)
    配置腾讯云轻量级linux服务器用到的资源和步骤
    CSS样式中的各种居中方式
    CSS浮动---float
  • 原文地址:https://www.cnblogs.com/jdzhang/p/8338461.html
Copyright © 2020-2023  润新知