![NETFramework中已使用的设计模式_第1页](http://file3.renrendoc.com/fileroot_temp3/2022-1/29/0e3ee752-bfd2-4c06-848a-50068c14c989/0e3ee752-bfd2-4c06-848a-50068c14c9891.gif)
![NETFramework中已使用的设计模式_第2页](http://file3.renrendoc.com/fileroot_temp3/2022-1/29/0e3ee752-bfd2-4c06-848a-50068c14c989/0e3ee752-bfd2-4c06-848a-50068c14c9892.gif)
![NETFramework中已使用的设计模式_第3页](http://file3.renrendoc.com/fileroot_temp3/2022-1/29/0e3ee752-bfd2-4c06-848a-50068c14c989/0e3ee752-bfd2-4c06-848a-50068c14c9893.gif)
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 NET(C#) In ternals: .NET Framework中已使用的设计模式2010-05-2920:01by 吴秦,2234visits, 网摘,收藏,编辑适合有一定设计模式基础和.NET基础的人阅读写在前面“设计模式”我一向是敬而远之的态度, 不会去写这方面的文章,原因有二:第 一,要想写好设计模式的文章太难,需要笔者丰富的经验;第二,没有深厚的功 底写出的设计模式文章容易误导他人。 自认没有深厚的功底,但我不会为了设计 模式而设计模式。我想大部分人对设计模式的理解是不够深刻的, 不然应用自如, 特别是初学者!所有研究高质量的源码或框架是我们学习实践设计模式的好途径 之一。而我
2、之所以写这篇文章,主要是因为它从.NETFramework入手介绍已经使用的设 计模式,作为一个.NET开发人员应该再熟悉不过了,能够有比较深刻的认识和 理解。本文从.NETFramework中入手,发掘在.NETFramework中如何使用设计模 式的。从中我们知道我们平时使用.NET时,我们使用了那些模式及学习使用设 计模式。本文意译自 Discover the Desig n Patter ns You're Already Us ing in the .NET Framework及加入了相关设计模式的 UML表示和主要介绍。主要内容如下:* .NETFramework中使用的观
3、察者模式(ObserverPattern )* .NETFramework中使用的迭代器模式(IteratorPattern* .NETFramework中使用的装饰模式(DecoratorPattern )« .NETFramework中使用的适配器模式(AdapterPattern .NETFramework中使用的工厂模式(FactoryPattern ) .NETFramework中使用的策略模式(StrategyPattern ) ASP.NET中的组合模式(CompositePattern .NETFramework中使用的模板方法模式(TemplateMethodPat
4、tern ) ASP.NET管道中的模式(PatternsintheASP.NETPipelineo 截取过滤器模式(InterceptingFilterPatterno 页面控制器模式(PageControllerPatterno ASP.NET中的其它web表示模式(OtherWebPresentationPatternsinASP.NET )*总结观察者模式:在此种模式中,一个目标物件管理所有相依于它的观察者物件, 并 且在它本身的状态改变时主动发出通知。这通常通过调用各观察者所提供的方法 来实现。它的UML表示如下:图1、观察者模式的UML表示(来源:维基百科)好的面向对象设计都强调
5、圭寸装(encapsulation )和松耦合(loosecoupling )。 换句话说,类应该保持内部细节私有并且最小化类之间严格的依赖关系。大部分应用程序,类并不是独立工作的,而是与其他类交互的。类交互的一个通常例子 是:一个类应该(观察者,Observer)被通知,当被观察者(Subject )的某些 东西改变了。例如,当单击一个按钮后可能某些Win dowsForms的控件需要更新他们的显示。一个简单的解决方案是,当状态改变时让被观察者调用观察者特定 的方法。但是,这回引入一连串的问题。因为被观察者需要知道调用哪个方法, 这样就与特定观察者产生了紧耦合(tightcoupli ng
6、)。而且,如果当需要添加 多个观察者时,不得不继续添加每个观察者方法调用的代码。如果观察者的数量动态地改变,这将变得更复杂。这将很难维护!应用观察者模式能有效地解决这个问题。可以从观察者解耦被观察者,因此在设 计时和运行时观察者可以容易地添加和移除。被观察者维护者一个对它感兴趣的 观察者列表,每次被观察者的状态改变时,它对每个观察者调用Notify方法。下面这段代码展示了一个实现示例:view source print?publicabstractclassCa noni calSubjectBase03040506070809101112131415161718privateArrayLis
7、t_observers=newArrayList(); publicvoidAdd(ICanonicalObservero)_observers.Add(o);publicvoidRemove(ICanonicalObservero)_observers.Remove(o);publicvoidNotify()foreach(ICanonicalObserveroin_observers)o.Notify();19 20voidNotify3 ();所有的观察者类实现ICanonicalObserver接口,所有的被观察者必须继承自 CanonicalSubjectBase。如果一个新的观察者
8、想监视被观察者,Add方法可以轻松的处理而不必改变被观察者类的代码。注意:每个被观察者仅仅直接依赖于ICa non icalObserver接口,而不是特定的观察者。然而使用GOF勺观察者模式解决这些问题仍有一些障碍,因为被观察者必须继承 一个特定的基类且观察者必须实现一个特定接口。考虑回Win dowsForms按钮的例子,.NETFramework引入了委托和事件来解决这些问题。如果你已经编写过 ASP.NET或WindowsForms程序,你可能就是有了事件和事件处理器。事件作为 被观察者,然而委托作为观察者。下面代码展示了使用事件的观察者模式:view source print?pub
9、licdelegatevoidEve nt1Ha nder();publicdelegatevoidEve nt2Ha ndler(i nta);publicclassSubject06 )07 1;08 2;09 ()1011 en t1;12publicSubject(publicEve nt1Ha nderEve ntpublicEve nt2Ha ndlerEve nt publicvoidRaiseEve nt1Eve nt1Ha ndlerev=Evif(ev!=null)ev();131415161718192021222324252627282930313publicvoidR
10、aiseEvent2()Event2Handlerev=Event2;if(ev!=null)ev(6)publicclassObserver1publicObserver1(Subjects)s.Event1+=newEvent1Hander(HandleEves.Event2+=newEvent2Handler(HandleEvent1);nt2);publicvoidHandleEvent1()233 )3435 2");3637 publicvoidHa ndleEve nt2(i ntaCon sole.WriteLi ne("Observer1-Eve ntWi
11、ndowsFormsButton控件公开一个 Click事件,当button被点击时产生。任何 设计为响应这个事件的类仅需要用这个事件注册一个委托。Butt on类不依赖与任何潜在的观察者,并且每个观察者仅需要知道这个事件的委托的正确类型(这里是EventHandler )。因为EventHandler是一个委托类型而不是一个接口,每 个观察者不需要实现一个额外的接口。假定它已经包含一个与签名兼容的方法, 只需要用被观察者的事件注册方法。通过使用委托和事件,观察者模式使被观察 者与观察者们之间解耦了。2、迭代器模式(IteratorPattern)迭代器模式:它可以让使用者通过特定的接口巡访容
12、器中的每一个元素而不用了 解底层的实作。它的UML表示如下:图2、迭代器模式的UML表示(来源:TerryLee的.NET设计模式(18):迭代器模式(Iterator Pattern)许多编程任务包括操作对象的集合。不管这些集合是简单的列表还是更复杂的, 如二叉树,经常需要访问集合中的每个对象。事实上,根据集合可能有几种不同 的访问每个对象的方法,诸如从前向后、从后向前、前序或后序。为了保持集合 简单,遍历代码通常放在自己单独的类中。存储一个对象列表的常用方法之一就是用数组。数组类型在VisualBasic.NET和C艸都是内置类型,他们都有一个循环结构用于在数组上迭代:foreach (C
13、#) 和ForEach(VisualBasic.NET )。下面是一个在数组上进行迭代的简单例子:view sourceprint?1 in tvalues=newin t1,2,3,4,5;22 foreach(i nti inv alues)3 _Co nsole.Write(i.ToStri ng()+"")5j4 这些语句在后台对数组使用了迭代器。我们需要知道的就是它保证了循环保证了对数组中的每个元素进行一次遍历。为了使这些语句起作用,foreach表达式中涉及的对象必须实现了IEnumerable接口。任何实现了 lEnumerable接口的对象集合都可以被遍历(
14、枚举)。这个接 口仅有一个方法GetEnumerator(),它返回一个实现了 lEnumerable的对象。lEnumerator接口包含遍历迭代集合所需要的代码,它有一个属性Current标识当前对象、方法MoveNext()移到下一个对象、方法 Reset()重新开始。System.Collections 命名空间中所有的集合类,及数组,都实现了 IEnumerable 接口,因此能被迭代。如果你测试了由C#编译器生成foreach的MSIL代码,你可以看到大部分情况它 仅使用IEnumerator去做迭代(特定类型,如数组和字符串,由编译器特别处理)。 下面代码展示用IEnumerat
15、or方法实现上例功能的代码:view sourceprint?1 in tvalues=newin t1,2,3,4,5;2 IEnu meratore=(IE nu merable)values).GetE nu merator();3 while(e.MoveNext()4 Co nsole.Write(e.Curre nt.ToStri ng()+"").NETFramework使用IEnumerable和IEnumerator接口实现了迭代器模式。迭代 器模式使我们能够轻松地遍历一个集合而不用了解集合内部的工作机制。一个迭代器类,实现了 IEnumerator接口,
16、是一个独立与集合的类,实现了 IEnumerable接口。迭代器类维护遍历的状态(包括当前元素是哪个和是否有更 多的元素要遍历)。这个遍历的算法也包含在迭代器类中。这种方法可以同时有几个迭代器,每个以不同的方式遍历同一个集合,而不会对集合类增加任何复杂。3、装饰模式(DecoratorPattern )装饰模式:一种动态地往一个类中添加新的行为的设计模式, 通过使用修饰模式, 可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹 的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。 修饰
17、类必须和原来的类有相同的接口。UML表示如下:ba&a.Operatlofi(t图3、装饰模式UML表示(来源:TerryLee 的.NET 设计模式(10):装饰模式(Decorator Pattern)任何有用的可执行程序包括读取输入或写输出, 或者都有。尽管数据源被读或写, 能够把它们抽象地看成字节序列。.NET使用类去表示这个抽 象。不管这些数据是包含在文本文件中字符,还是 TCP/IP网络流的数据,或任 何其他实体中,你将通过一个 Stream访问它们。因为用于文件数据的类(FileStream )和用于网络流的类(NetWorkStream)都继承自Stream,你可以 简
18、单地编写独立于数据源的代码处理数据。下面的代码展示从一个Stream中打印字节到控制台:view source print?1 publicstaticvoidPri ntBytes(Streams)2 34in tb;while(b=fs.ReadByte()>=0)56 +"");Con sole.Write(b7每次读取单个字节通常不是最高效的访问流的方法。例如,硬件驱动器有能力(且 优化了)从磁盘的一大块中读取连续的数据块。如果你知道你将读取几个字符, 最好一次从磁盘中读取一个块然后从内存中逐字节地使用。框架包括BufferedStream类就是做这个的。Bu
19、fferedStream的构造函数以流的类型为参 数,设定你想缓存访问的类型。BufferedStream重写了 Stream的主要方法,诸 如Read和Write,提供更多的功能。因为它仍然是 Stream的子类,你可以想其 他Stream 一样使用它(Note: FileStream 包括他自己的缓存能力)。类似地, 你可以使用 System.Security.Cryptography.CryptoStream加密和解密流(Streams),除了它是一个流应用程序不需要知道任何其他的东西。下面展示 了几种使用不同的Streams调用打印方法:view sourceprint?1 Memor
20、yStreamms=n ewMemoryStream( newbyte1,2,3,4,5,6,7,8);2 Prin tBytes(ms);3 BufferedStreambuff= newBufferedStream(ms);4 Prin tBytes(buff); ",F5 buff.Close();6 FileStreamfs=n ewFileStream(” ileMode.Ope n);7 Prin tBytes(fs);8 fs.Close();FIMtnwStrtdiHPrintSlreav图4、使用装饰模式使用组合动态透明地附加新功能到对象的能力是装饰模式的例子,如上
21、图所示。给定任何Stream的的实例,你可以通过包装在一个 BufferedStream中添加缓冲 访问的能力,而不用改变接口数据。因为你仅仅是组合了对象,这可以在运行时 做,而不像继承是编译时决定的。核心功能通过一个接口或者抽象类(如Stream) 定义,所有装饰都派生自它。这些装饰自己实现(或重写)接口(或抽象类)中 的方法以提供额外的功能。例如BufferedStream重写Read方法从缓冲中读取流, 而不是直接从流中读取。如上面的代码所示,任何装饰的组合,不管多复杂,可 以像只有基类一样使用。4、适配器模式(AdapterPattern )适配器模式:将一个类别的接口转接成用户所期待
22、的。 一个适配使得因接口不兼 容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存 在的类中。有两类适配器模式:对象适配器模式一一在这种适配器模式中,适配器容纳一个它我包裹的类 的实例。在这种情况下,适配器调用被包裹对象的物理实体。类适配器模式一一这种适配器模式下, 适配器继承自已实现的类(一般多 重继承)。他们的UML表示分别如下:图5、对象适配器模式图6类适配器模式(来源:TerryLee的.NET设计模式(8):适配器模式(AdapterPattern ).NETFramework的优势之一就是向后兼容性。从基于.NET的代码可以轻松的访问 旧的COM寸象,反之亦然。为
23、了在项目中使用 COMA件,必须在VisualStudio 中通过添加引用对话框添加引用。在后台VisualStudio.NET调用tlbimp.exe工具创建一个包含在in terop程序集中的运行时可调用包装(Run timeCallableWrapper , RC)类。一旦添加了引用(且 in terop 程序集已 经生产了),COMS件就可以像其它托管代码类一样使用。如果你在看别人写的 代码没有看到引用列表(且没有坚持类关联的元数据或他们的实现),你将不知 道哪些类是用.NET的语言写的,哪些是 COMA件。使这种神奇发生的是RCM COMA件有不同的错误处理机制及使用不同的数据类型。
24、例如.NETFramework中的字符串使用System.String 类,而COM可能使用BSTR 当在.NET代码中用一个字符串调用 COM&件时,你可以像其它托管代码方法一 样传递一个System.String 。在RCV内部,在COh调用之前,这个System.String 转换成COM组件期望的格式,就像BSTR类似地,COM组件的一个方法调用典型 地返回HRESUL表示成功或失败。当一个COM方法调用返回表示失败的 HRESULT 时,RCV转化成一个异常(默认情况下),因此它能像其他托管代码错误一样处 理。尽管它们的接口不一样,但还是允许托管类和COM组件交互,RCW是适
25、配器模式的例子。适配器模式使一个接口适合另一个,COM并不理解System.String类, 因此RCW1配器使其适应为可以理解的。即使你不能改变旧的组件工作机制,你 仍可以与它交互。这种情况经常使用适配器。适配器类本身包含了一个适配(Adaptee),将来自客户端的调用转化为合适的 和顺序的调用。虽然听起来像装饰模式,它们之间有几个关键的不同。装饰模式中,组合的对象接口是相同的;适配器模式中,你可以改变整个 接口。适配器模式中,给他们定义了一个明确的序列,适配必须包含在适配器中; 装饰模式中,装饰类不必知道它包装了 1个或500个其它类,因为接口是 相同的。因此使用装饰模式对应用程序时透明的
26、,然而使用适配器模式不是。5、工厂模式(FactoryPattern )工厂模式:通过调用不同的方法返回需要的类, 而不是去实例化具体的类。对实 例创建进行了包装。工厂方法是一组方法,他们针对不同条件返回不同的类实例, 这些类一般有共同的父类。它的 UML表示如下:图7、工厂模式的UML表示(来源:TerryLee的.NET设计模式(5):工厂方法模式(Factory Method )许多情况下,在框架(Framework)中你可以自己不调用一个 struct或class 的构造器而获取一个新的实例。System.C on vert类包含了一系列的静态方法向 这样工作。例如,将一个整数转换为布
27、尔类型,你可以调用Con vert.ToBollean并传递一个整数。如果整数是一个非零值则这个方法的返回值是一个新的Boolean并设为“ true ”,否则是“ false ”。Con vert类为我们创建Boolean 实例,并设为正确的值,其它的类型转换也是类似。Int32和Double上的Parse 方法返回这些对象的新实例并根据给定的字符串设置合适的值。这种创建新对象实例的策略称为工厂模式。不用调用对象的构造器,你可以要 求对象工厂为你创建一个实例。如此一来可以隐藏创建对象的复杂性(就像如何 从一个字符串解析为一个Double值,Double.Parse )。如果你想改变创建对象
28、的细节,你仅需要改变工厂它本身,你不必修改每个调用构造器的地方。这些类型转换方法是工厂模式的变种,因为在问题中你不必使用这个工厂创建对 象。一个更纯的工厂模式的例子是 类,用来发出请求(request )和从In ternet 上的资源接受响应(respo nse )。FTP HTTP和文件 系统请求默认页支持。为了创建一个请求,调用Create方法和传递一个URI。Create方法决定合适的请求协议,且返回合适的WebReques的子类:HttpWebRequest、FtpWebReques( .NETFramework2.0新增的)、FileWebRequest。 调用者不需要知道每个特定
29、的协议,仅需知道如何调用工厂和使用WebRequest获取返回值。如果URI从一个HTTP地址改变为FTP地址,代码根本不用改变。 这是工厂模式的另一种常用用法。 父类作为一个工厂,且根据客户端传递的参数 返回特定派生类。就像 WebRequest例子,它隐藏了选择合适派生类的复杂性。6 策略模式(StrategyPattern ) 策略模式:指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。 比如每个人都要“交个人所得税”,但是“在美国交个人所得税”和“在中国交 个人所得税”就有不同的算税方法。它的 UML表示如下:策略模式的UML表示(来源:维基百科)数组(Array )和数组
30、列表(ArrayList )都提供通过Sort方法对集合中的对象 排序的功能。实际上,ArrayList.Sort 仅对隐含的数组调用Sort。这些方法使 用的是快速排序(QuickSor)算法。默认,Sort方法使用IComparable实现每 个元素之间的比较。有时,使用不同的方法对同一列表排序非常有用。例如,字符串数组的排序可能是对大小写敏感的或不区分大小写的。要做到这点,Sort函数存在重载并以一个IComparer作为参数;然后IComparer.Compare用于进行 比较。重载允许类的用户任何内置的ICompares或自定义的,而不用做修改甚至 不用知道Array、ArrayLi
31、st、或Quicksort算法的实现细节。将比较算法的选择留给类的用户,像这种情况就是策略模式。使用策略模式允许 有许多不同的可替换的算法。Quicksort本身只需要一个方法来相互比较对象。 通过提供一个接口调用比较,由调用方自由选择可替换的适合特定需要的比较算 法。Quicksort的代码可以保持不改变。J AJcMitha Viriawt 1 F1 . T" 1 I 1 T . E j iF '51 Algorithm Vidant 2图9、策略行为.NETFramework2.0的一个新的泛型集合类型 List<T>,还利用大量使用的策 略模式,如上图所示
32、。除了更新了排序方法,find-related方法,BinarySearch,其它以根据调用者需求改变算法的参数。在FindAII<T>方法中使用一个Predicate<T>委托使调用者使用任何方法作为 List<T>的过滤器,只要它接受的 对象类型并返回一个布尔值。组合匿名方法,客户可以容易地基于属性和列表中 对象的方法过滤列表,而不用引入依赖于List<T>类本身。使用策略模式使复杂的处理过程,诸如排序,容易地修改以适合特定的目的,这意味着你可以编写和维护较少的代码。7、ASP.NET中的组合模式(CompositePattern )组合模式
33、:将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和使用具有一致性。它的 UML表示为:CI ientforaach child in child nanchild .QpeiBLjOMf)I图10、组合模式的UML表示(来源:TerryLee的.NET设计模式(11):组合模式(Composite Pattern )ASP.NET的request/response 管道(pipeline )是一个复杂的系统。模式用于设计管道本身和控件体系结构有效地平衡它的可扩展性能和简化编程。在深入挖掘管道之前,我们检查编程模型本身使用的模式。当处理对象集合时,通常适合单个对象和
34、整个集合。 考虑一个ASP.NET控件,- 个控件可能是一个简单的单个元素如 Literal ,或可能是一个有子控件的复杂的 集合如DataGrid。不管怎样,任一这些控件上调用 Render方法都将执行相同的 显示功能。当集合的每个元素可能自己包含其它对象的集合时,使用组合模式是合适的。组合模式是一个简单的方法来表示树形集合,而不用对父节点和叶子节点区别对象。组合模式的权威例子是依赖于一个抽象基类,Compo nent包含添加和删除孩子、 孩子和父亲之间的通用操作方法。 ASP.NET正是对使用 这种模式。Control表示Component基类,它有一些操作,诸如处理子控件(如 子空间属性
35、)、标准操作、属性如Render和Visible (译注:定义由所有ASP.NET 服务器控件共享的属性、方法和事件)。每个对象,不管是原始的对象(如Literal ) 或组合对象(如DataGrid ),读继承自这个基类。因为控件是多样的,有一些中间继承类如 WebControl和BaseDataList,是其它 控件的基类。虽然这些类公开一些额外的属性和方法,但他们仍然保留孩子的管 理功能和从Control继承的核心操作。事实上,使用组合模式有助于隐藏他们的 复杂性,如果需要的话。 不管是一个Literal控件还是一个DataGrid控件,使 用组合模式意味着你仅需要调用 Ren der,
36、事情会自行解决。8、模板方法模式(TemplateMethodPattern ) 模板方法模式:定义了一个算法的步骤,并允许次类别为一个或多个步骤提供其 实践方式。让次类别在不改变算法架构的情况下,重新定义算法中的某些步骤。 模板方法多用在:某些类别的算法中,实做了相同的方法,造成程序码的重复 控制次类别必须遵守的一些事项。它的UML表示如下:U .、G AhsiraciClasaoonneTningOjif,”,Fr imi i wQpealion 耳 it.FFinitjOyEntianlPrimli«Optrailoril()jPrinidi 足 Opentthn?屯irdoA
37、ht-Q d TanplalE LlEtho d QIt .一 d»SoiTiEiiiingQ建 CcncreteClass,I Frunib总OpradoniqFmirtiJEO-pritiKinZQ图11、模板方法的UML表示(来源:一 d»Soin»thhiig(|维基百科)当ASP.NET控件的标准库满足不了你的需求,你有几种选择如何创建自己的。对 简单的控件仅用在一个项目中,用户控件是最好的选择。当控件用在集合 Web 应用程序中或要求更多的功能,一个自定义服务器控件也许是最好的选择。当处理自定义控件,有两个一般的类型:控件组合已存在的控件的功能(称为组
38、 合模式)、控件有一个唯一的视觉表示。处理创建这些类型的控件的过程类似。对应组合控件,创建一个新的类继承自一个控件基类(像Control或WebControl), 然后重写CreateChildControls 方法(译注:该方法由 ASP.NET页面框架调用, 以通知使用基于合成的实现的服务器控件创建它们包含的任何子控件,以便为回发或呈现做准备)。对于其它自定义控件,你需要重写的 Ren der且使用 HtmITextWriter参数用于为你的控件直接输出 HTML不管你选择的自定义控件的样式,你不必写任何处理所有控件通用的功能,如在适当的时间加载和保存 ViewState,允许PostBa
39、ck事件去处理,且确保控件的 生命周期事件以正确的顺序发生。控件怎么样加载、呈现、卸载的主要算法包含 在控件基类中。你的控件的特定细节在控件算法的特定地方实现(CreateChildCo ntrols 或 Ren der方法)。这是模板方法模式的一个例子。主要算法框架定义在一个基类中,且子类可以插入他们自己的细节而不影响算法本身,如图12所示。一个组合控件和一个自定义控件都共享同样的一般生命周期,但是他们以完全不同的视ClMtAVtdtrt: CImU DtStmrlhinW 1SR. 1DvtrrMt St*i 1觉表示。图12、模板方法模式这个模式类似于策略模式,他们在范围和方法上不同。策
40、略模式用于允许调用者改变整个算法,例如如何比较两个对象,然而 模板方法模式用于改变算法的步骤。正是因为这点,策略模式是更粗粒度 的,他们的不同客户端实现可以有巨大的不同,然而模板方法模式保持框架相同。另一个主要不同点是,策略模式使用委托,然而模板方法模式使用继承。 上面排序例子的策略模式,比较算法委托于IComparer参数;但是自定义 控件中,你子类的基类和重写方法去做改变。然而,他们都使你容易地修改处理过程以适合你的特定需求。9、ASP.NET管道中的模式(PatternsintheASP.NETPipeline )当客户端请求一个ASPX网页,在最终以HTML显示到客户端的浏览器之前,请
41、求 穿过许多步骤。首先,请求被IIS处理和路由到合适的ISAPI扩展。ASP.NET的 ISAPI 扩展(aspnet_isapi.dll )路由请求到 ASP.NETT作进程。13、ASP.NET青求管道在这一点,请求开始与处理请求的类进行交互。请求被传递到一个HttpApplication 。一般地,这个类在 Global.asax的后置代码文件中创建。 HttpApplicati on然后传递请求给一些 HTTP模块。这些类实现了 IHttpModule接口且在传递给下一模块之前可以修改请求(甚至可以停止请求)。ASP.NET提供了一些标准的模块提供常用的功能,包括FormsAuthe
42、nticatio nM odule、PassportAuthe nticati onM odule、Win dowsAuthe nticatio n 、Sessi on StateModule等等。最终,请求结束在一个IHttpHandler,最常用的是 的 IHttpHandler.ProcessRequest 方法。Page产生合适的事件(例如 Init、Load、 Render),处理ViewState,提供ASP.NET勺编程模型。图13展示了一个整理 轮廓。在这个处理过程中采用了几个模式,更深入的可以参考Marti nF owler's PatternsofE nterpri
43、seApplicatio nArchitecture(Addis on-Wes ley,2002)。下面介绍其中用到的几个模式。9.1、截取过滤器模式(InterceptingFilterPattern)一旦一个请求到达 HttpApplication ,它将传递到一些IHttpModules 。每个模块 是独立的且仅有数量有限的控制加在调用顺序上。HttpApplication 类公开一系 列的事件,在请求的处理过程中产生这些事件包括 Beg in Request、AuthenticateRequest 、 AuthorizeRequest 、 EndRequest。当 HttpApplic
44、ation 加载一个模块,它调用IHttpModule接口的Init方法,允许模块注册关心它的 一些事件。作为一个给定的请求被处理,事件以合适的顺序产生且所有注册的模 块可以与请求交互。因此,模块可以控制在它被调用的阶段,但不是这一阶段的确切顺序。这些模块是截取过滤模式的例子, 这个模式表示一个过滤器链,每个过滤器依次 有机会修改请求(或消息)传递他们。图 14展示了这个过程的一个简单的流程 图。这个模式的关键思想是过滤器是独立的, 过滤器可以修改传递到它的请求。图14、请求流程有几种不同的截取过滤器模式变种的实现,一种是 ASP.NET勺基于事件的模型。 一个简单的变种包括维护一个过滤器列表
45、并对它迭代,依次对它们每个调用一个 方法。这是 WebServiceEnhancements (WSE 为 ASP.ENTService如何使用这个 模式。每个过滤器扩展自SoaplnputFilter (为请求消息)或SoapOutputFilter(为响应),重写ProcessMessage方法执行过滤器的工作。另外一种选择是通过装饰模式实现截取过滤器。每个过滤器将包装它的后继,执行预处理,调用它的后继,然后执行后处理。通过递归组合构建链,从后往前。 这个模式用于实现.NETRemoting管道接收器。无论其实现,结果是独立过滤器的动态可配置链。因为他们是独立的,这些过滤 器可以容易地在其他应用程序中重排序和重用。通用任务如身份鉴定或日志可以封装在一个过滤器中且反复使用。这些任务可以在请求到达HttpHandler之前被 过滤器链处理,保持处理代码整洁。9.2、页面控制器模式(PageControllerPattern)实现ASP.NET编程模型的核心部分。每当你要添加一个逻 辑页面到一个 Web应用程序,你可以创建一个 WebFor(通过一个ASPX文件和 它的后置代码文件表示)。然后你可以编写代码处理新页面的具体需求,无论是 通过处理页面级事件,显示一个组控件,或加载和操作数据。应用程序中的每个 逻辑页面有一个相应的WebForm
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中国智能座舱行业市场规模及发展前景研究报告(智研咨询)
- 知识产权与专利情报课件
- (高清版)DB37∕T 3046-2017 苦楝栽培技术规程
- (高清版)DB37∕T 2982.2-2017 海洋牧场建设规范 第2部分:调查与选址
- 《植物旳向性运动》课件
- (高清版)DB23∕T 3890-2024 公路工程蜂格护坡技术规范
- 《管理角色认知》课件
- 大学生创新创业教程(慕课版 双色版 第3版) 课件 第3章 创业与创业政策
- 2025至2031年中国带混床除盐系统设备行业投资前景及策略咨询研究报告
- 2025至2031年中国基站控制单元行业投资前景及策略咨询研究报告
- 青岛生建z28-75滚丝机说明书
- 公务员面试应急应变题目大全及解析
- 学校年级组长工作计划
- 2023年广州市青年教师初中数学解题比赛决赛试卷
- 对折剪纸课件
- 膝关节痛风的影像学诊断
- 方案设计初步设计施工图设计要求模板
- 新中国成立后的中国国防
- 2023-2024人教版小学2二年级数学下册(全册)教案【新教材】
- 浙江省炮制规范2015版电子版
- 小学《体育与健康》体育基础理论知识
评论
0/150
提交评论