举手投足项目开发笔记(.Net下的观望者(Observer)方式)

单个java对象输入校验:

 

    

 

*率先个文件是Action的校验文件。该文件中由于Action的私房变量是一个Material对象。因而代码中fieldname是该变量名字,定义了几个参数。一个是context参数,所定义的名字是有开发者自己随便定义。然而之后Material对象的输入校验配置文件名字中务必有那几个名字。

*第四个文本校验配置文件名字命名格式是“Java对象名-context参数-validation.xml”,而在本示例中是”Material-materialContext-validation.xml”,该文件一定要和Java对象的类代码文件放在同等目录下。

图片 1

 

<wiz_tmp_tag id=”wiz-table-range-border” contenteditable=”false”
style=”display: none;”>

 

 

 

 

 

其中KnowType是一个自定义的特性,代码如下:

validate方法举行输入校验:

   
struts最基本办法是在每个Action中继承ActionSupport类,并且重写它的输入校验方法validate()。本示例中的RegisterAction代码中也展现,依据页面上输入的各个校验将持有不吻合输入校验规则的错误音信都由ActionSupport类中另一个主意add菲尔德(Field)Error方法将错误音讯参预到表单错误新闻,并且在输入数据的页面突显,不会再由Action导航到注册成功页面。

 

• 
使用面向对象的肤浅,Observer形式使得大家得以独立地改成目的与寓目者,从而使二者之间的依赖关系达致松耦合。

validateXXX方法进行输入校验:

    Struts
2中除去validate方法之外它还有一种validateXXX方法针对Action中某一一定措施开展该办法的各样字段的输入校验。其中XXX就是该特定措施名。validate方法是对具有Action中方法的输入校验都进行校验,validateRegister方法只对Register方法举行校验。因而双方无法重复使用,都利用会促成几个方法都进行了校验的结果。

在软件构建进程中,大家需求为一些对象建立一种 “布告信赖关系”
——一个对象(目的对象)的气象爆发改变,所有的依赖对象(观望者对象)都将得
到通告。如若如此的信赖关系过度紧密,将使软件无法很好地抗击变化。

行使配置文件进行输入校验:(常用)

 
  使用安顿文件来形成输入校验这种措施,首先在Action代码中删去所有validate和validateXXX方法的代码。然后在和Action类文件同超级目录下扩张XXX-validation.xml配置文件。那里”XXX”是Action类文件名字,表示该XML文件中兼有输入校验的平整定义和错误音讯突显模式都只针对该Action有效。

    字段校验:

 

   非字段校验:

 

 

六、项目中使用的布告订阅形式的莫过于例子:(那里其实利用了observer情势的恢宏)须要是:当一个对象的情景暴发了变动(那里是流传一个音讯给一个对象),那么富有监听这一个目的的其余对象会依照指定的收纳目的的类型调用指定对象的不二法门:大家都很精通的垂询到observer方式首要是用于当一个对象的情景爆发变化的时候,会自行的通知订阅的其余对象,也就是说会把当前的信息传递给别的对象举行拍卖。不过有一个题材是,假如此外对象收取到的信息是由限制的,像某个对象只好收到指定项目的音讯等,那样的话就需求在在此在此以前的observer方式上进展补偿:

        public KnowTypeAttribute(Type modelType)
        {
            this.m_typeName = modelType.FullName;
        }
    }

   public interface IActionListener
    {
        /// <summary>
        /// 订阅接受方法
        /// </summary>
        /// <param name=”value”>Domain Model or Data Entity</param>
        /// <returns>执行成功再次回到True,否则为false</returns>
        bool Run(object value);
    }

此间就不突显其余代码了,总而言之思想就是那样,通过在Listener的类公事中经过性能来制订那么些目标接受的新闻类型,最终遍历所有的监听者对象看是不是满足指定的音讯类型,最后调用指定的目的的格局。那样就落成了种类中的必要。

• 
目的发送公告时,无需指定观看者,文告(可以指点公告音信作为参数)会自行传播。观望者自己决定是否要求订阅布告,目标对象对此一无所
知。

IActionListener是一个接口:

 

推荐资源
* 《设计格局:可复用面向对象软件的底子》GoF
* 《面向对象分析与安顿》Grady
Booch
* 《敏捷软件开发:原则、格局与实践》罗伯特(Robert)(Robert)C. 马丁
* 《重构:改良既有代码的安排性》马丁福勒(Fowler)
* 《Refactoring to Patterns》Joshua Kerievsky
 更多MSDN资源
* MSDN普通话网站
http://www.microsoft.com/china/msdn 
* MSDN普通话网络广播
http://www.msdnwebcast.com.cn/
* MSDN Flash
http://www.microsoft.com/china/newsletter/case/msdn.aspx 
* MSDN开发中央
http://www.microsoft.com/china/msdn/DeveloperCenter/default.mspx

三、意图(Intent)

五、Observer格局的多少个大旨

下边是项目中有关这一个情势的的构造如图:

二、动机(Motivation)

        public string TypeName
        {
            get { return m_typeName; }
        }

 

 

图片 2

里面的主导措施是因此反射得到所有监听的对象所须要接受对象的门类,那样就足以调用指定对象的不二法门,而不是调用所有监听者的方法:上面是其一方式的主导:

注册监听目标目标是透过代码指定的,当然可以经过一个xml文件来配置节点来促成,那样会越来越灵敏

图片 3图片 4Code
        private static Dictionary<string, RegisteredListener> registeredContainer;
        private static MonitorConfiguration configuration;
        static MonitorFactory()
        {
            configuration = new MonitorConfiguration();
            configuration.Listeners = new List<ListenerItem>();

 

图片 5

            ListenerItem item = new ListenerItem();
            item.ClassName = “ProjectEstablishRequestListener”;
            configuration.Listeners.Add(item);
            item = new ListenerItem();
            item.ClassName = “ProjectApprovalListener”;
            configuration.Listeners.Add(item);
            item = new ListenerItem();
            item.ClassName = “DesignApprovalListener”;
            configuration.Listeners.Add(item); 
            
            registeredContainer = new Dictionary<string, RegisteredListener>();
            foreach (ListenerItem listener in configuration.Listeners)
            {
                if (listener.Valid)
                {
                    ActivatorListener(listener.ClassName);
                }
            }
        }

图片 6图片 7Code
 public static bool Publisher(object arg)
        {
            bool result = false;
            if (configuration != null && configuration.Listeners != null && configuration.Listeners.Count > 0)
            {
                RegisteredListener listener = null;
                foreach (ListenerItem item in configuration.Listeners)
                {
                    if (item.Valid)
                    {
                        listener = ActivatorListener(item.ClassName);
                        if (listener != null)
                        {
                            if (listener.RegisteredTypes == null || listener.RegisteredTypes.Length == 0)
                            {
                               result= listener.CurrentListener.Run(arg);
                            }
                            else
                            {
                                foreach (KnowTypeAttribute attributeItem in listener.RegisteredTypes)
                                {
                                    if (arg.GetType().FullName == attributeItem.TypeName)
                                    {
                                        result=listener.CurrentListener.Run(arg);//那里是调用指定对象的方法
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return result;
        }

四、结构
图片 8 

图片 9图片 10Code
  /// <summary>
        /// 创设Listener实例并获得Attribute
        /// </summary>
        /// <param name=”className”></param>
        /// <returns></returns>
        private static RegisteredListener ActivatorListener(string className)
        {
            RegisteredListener result = null;
            if (registeredContainer.ContainsKey(className))
            {
                result = registeredContainer[className];
            }
            else
            {
                Type type = Type.GetType(className);
                if (type != null)
                {
                    KnowTypeAttribute[] registerType = type.GetCustomAttributes(typeof(KnowTypeAttribute), false) as KnowTypeAttribute[];
                    IActionListener listenerInstance = Activator.CreateInstance(type) as IActionListener;
                    result = new RegisteredListener(listenerInstance, registerType);
                    registeredContainer.Add(className, result);
                }
            }
            return result;
        }

概念对象间的一种一对多的看重关系,以便当一个对象的情况爆发变更时,所有依赖于它的靶子都得到公告并自动更新   
——《设计情势》GoF

    [KnowType(typeof(float))]
    public class DesignApprovalListener:IActionListener
    {
         public bool Run(object value)
        {
            return true;
        }
    }

  [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public class KnowTypeAttribute : Attribute
    {
        private string m_typeName;

Core文件夹下的MonitorFactory.cs文件就是已毕那些成效,代码如下:

第一来探视Listener文件夹下的一个文本(其他几个公文类似)

• 
在C#的event中,委托充当了用空想来欺骗别人的Observer接口,而提供事件的对象担任了对象对象。委托是比抽象Observer接口更为松耦合的宏图。

一、发布订阅模型(pub-sub)

 

上边是有些有关那些Observer的主导一些定义,在无数地方都能见到,那里我概括那那里便于以后翻看:

选拔面向对象技术,能够将那种借助关系弱化,并摇身一变一种祥和的依靠关系。从而完毕软件种类结构的松耦合。