Spring系列(3/4)----一个较为完善的模型(完)

来源:互联网 发布:吃肉 知乎 编辑:程序博客网 时间:2024/06/10 23:10

接上一篇,我们继续来完善这个模型,我们为附加责任类定义了一个接口,这样,只要实现这个接口的类都可以注册,接收代理类的调用通知;同时为了更好的交互,我们还定义了一个调用参数接口,和一个具体的调用参数类,接下来,我们再看看代理类:

/// <summary>
    /// 代理类,从AClass继承.
    /// </summary>
    public class ProxyAClass1 : AClass
    {
      
        private AClass _target;
        public Dictionary<IMethodExecNotify,MethodSubjectType> _observers = null;
        /// <summary>
        /// 构造函数,需传入目标类实例.
        /// </summary>
        /// <param name="target"></param>
        public ProxyAClass1(AClass Target)
        {
            _target = Target;
            _observers = new Dictionary<IMethodExecNotify,MethodSubjectType>();
        }
        public void RegisterOberver(IMethodExecNotify Observer,MethodSubjectType)
        {
            //.........
        }
        public void RemoveOberver(IMethodExecNotify Observer)
        {
            //..........
        }
        /// <summary>
        /// 执行方法实例.
        /// </summary>
        public override void Save()
        {
            object theRet = null;
            try
            {
                MethodInfo theMI = _target.GetType().GetMethod("Save",new Type[]{});
                var theAs = from item in _observers
                           where item.Value==MethodSubjectType.A
                           select item.Key;
                foreach(var item in theAs)
                {
                    object[] theParams = new object[]{};
                    IMethodInvocation theInvocation = new NotifyInvocation(_target,theMI,theParams);
                    item.SubjectMethodExecuting(theInvocation);

                }
                bool CanExecuteTargetMethod = true;
                 var theBs = from item in _observers
                           where item.Value==MethodSubjectType.B1
                           select item.Key;
                foreach(var item in theBs)
                {
                    object[] theParams = new object[]{};
                    IMethodInvocation theInvocation = new NotifyInvocation(_target,theMI,theParams);
                   CanExecuteTargetMethod = CanExecuteTargetMethod && bool.Parse(item.SubjectMethodExecuting(theInvocation).ToString());
                }
                if(CanExecuteTargetMethod==true)
                {
                    theRet = _target.Save(); 
                    //.......
                }
                //.....
                return theRet;

            }
            catch
            {
                //.......
            }
            finally
            {
                //......
            }
        }
    }

上面的调用比较复杂,实际应用可能不需要分这么多切入点。对于可以阻止目标类方法执行的逻辑(红色代码部分),可以根据自己的需要来决定如何决策。

但目前这个代理类作为一个静态示例还是可以的,但要作为动态代理类,跟前面的最初的代理原型一样,无法使用,因为注册管理功能无法使用,编译上过不去,如果采用反射来调用,是可以,但每次都这样使用,很麻烦。当然,这个改善很容易,只要将观察者类集合作为参数在构造函数中传递进去就可以了。但注册管理的责任谁来负责呢?我们前面分析过,因为代理类需要动态生成,而且动态代理类的形式和逻辑基本都一致,也适合动态生成,为了使用方便,我们可以提供一个工厂类来专门负责这件事情。那么自然而然,观察者注册管理的功能也自然由其完成,代理类工厂在构造代理类的时候,再将观察者集合作为构造函数的参数传入代理类,当然,观察者的通知执行还是由代理类来完成。而代理类工厂就是这个系列中第1篇中提到MyProxyFactory类的作用。

到这里,面向AOP编程的动态代理模型就基本成型了,当然,还有许多地方可以改善,但原理如此,大家可以根据自己的需要去继续改造。

下一篇,我们就来总结一下动态代理技术。

 

0 0
原创粉丝点击