|
第一部分: Provider模式统览
Provider设计模式是在.NET 1.1 framework中被首次介绍到,特别是在ASP.NET快速入门中,以及后来在ASP.NET Whidbey中作为membership management provider API被正式化。它的主要目的在于为一个API进行定义和实现的分离。这样就通过核心功能的灵活性和易于修改的特点使得API具有灵活性。
在MSDN上能找到关于此模式在.NET 1.1 Framework的更多信息:
http://msdn.microsoft.com/library/default.ASP?url=/library/en-us/dnASPNET/html/ASP02182004.ASP
和
http://msdn.microsoft.com/library/default.ASP?url=/library/en-us/dnASPNET/html/ASP02182004.ASP
Provider设计模式基本上是由GOF的两个设计模式溶合而成的:strategy和abstract factory。API定义好,其功能通过strategy模式变异而来,是“可插(拔)”的,而功能被加载进内存则是通过大致地一个abstractfactory设计模式而实现的。
以下是此部分基本概要,以及它们如何互交。
1. API Class:这是一个通过静态方法定义和暴露所需功能的类,在API Class中并没有具体的实现。此类保持一个对Application ProviderBase类的引用,这个base类会对API中的功能进行基本的包装(Wrap)。
本文中的API Class是一个商店(Store)我们可以从中买东西,如Coke(可乐)、Snickers(译者:不知道这是啥。),还有在吃Snicker和喝Coke时所要的diet pills(减肥药)。
我们的类包括以下几部分:
A:我们有基本的API用于存放货物AddProductToStock,还有如GetProductPrice、GetProductStockCount以及RemoveProductFromStock等核心方法。
B:我们有个叫Initialize()的方法用于从系统配置文件中加载已有的具体商店。
C:我们有所有可用Provider的引用。
D:我们有一个默认Provider的引用,此Provider已被包装。
一旦实例化,所有对这个API类的请求都会一个一个地转给默认的Provider。
2. Provider Base Class:这是一个内部抽象类,位于System.Configuration.Provider命名空间,用于定义一个Provider。Initialize()方法用于从配置文件中获取必要的信息来构建具体的Provider。我们在自己实现这个抽象类的时候要记的重写Initialize()方法。
3. Application ProviderBase:这是一个从ProviderBase类继承来的一个抽象类,同时也是API类的一个“镜像”,通过在API中所暴露的方法来为父类定义抽象方法并在父类中实现。
在我们的应用程序中我们把这个类叫做“StoreProvider”,请注意这个Store Provider是如何定义在Store类中已有的方法,同时从ProviderBase类继承。
4. Concrete Provider:Application Provider Base中所定义的方法在这个类中实现。Concrete Provider为了从配置文件中读取信息而会重写Initialize()方法
这四个类是实现Provider模式所必须的。其它的类则是用来定义一个Provider能提供什么东西(在本文中,是一个Product类)或是在以后为这些对象提供服务的工具类,或是用于管理程序配置文件。
这些东西看起来有点晕,不过当你看到一个请求传给Store类后再转交给一个StoreProvider的引用,由具体的CornerStoreProvider去完成时,你就知道这几个“齿轮”是如何配合的了。
第二部分:细节,细节,还是细节~
现在我们已经大概了解了一下基础了。好,再让我们把程序深入一些。首先我们构建一个API用于和商店以及商店中的货物(或是叫产品)互交。
看看这个货物(或是叫产品,下同)类:
这个类并不是Provider模式的一部分,我们只是用它来把数据搬进搬出而已。我们为每个货物定义名字和批发价。每个商店自己的货物都有自己不同的售价,所以我们还要计算这些货物的零售价。我也添加了一个静态方法来得到所有可用的货物:GetProducts()和 Initialize()
Store类定义了核心方法给我们(客户端),从store和products体现。
StoreProvider暴露了我们早先提到的抽象类中的方法
CornerStoreProvider是我们Store Provider类的具体实现。
VendingMachineStoreProvider是Store Provider类的另一具体实现。
Initialize()是每一个具体类都要实现的一个有趣方法。这个方法存在于ProviderBase中,但由ProvidersHelper调用。以下方法重写ProviderBase中的Initialize并从配置文件的节点中读取所需要的信息:
1 xml version="1.0" encoding="utf-8" ?>2
3 <configuration>
4
5 <configSections>
6
7 <section name="store" type="ProviderSample.StoreProviderConfigurationSection,
8
9 ProviderSample, Version=1.0.0.0,
10
11 Culture=neutral,PublicKeyToken=null" />
12
13 configSections>
14
15 <store defaultProvider="CornerStoreProvider">
16
17 <providers>
18
19 <add name="VendingMachineStoreProvider"
20
21 type="VendingMachineStoreProvider"
22
23 Coke="0.75"
24
25 Snickers="0.5"
26
27 Diet_Pills="1.25"
28
29 >add>
30
31 <add name="CornerStoreProvider"
32
33 type="CornerStoreProvider"
34
35 Coke="0.70"
36
37 Snickers="0.65"
38
39 Diet_Pills=".80"
40
41 >add>
42
43 providers>
44
45 store>
46
47 configuration>
第三部分:执行
为了使用我们的API,我们要对静态的Store类进行方法调用,在本次示例中如果我们默认的provider存有产品,我们可以通过API类(Store)提供的方法使用默认provider。
1 // Get some coke NET技术:.NET 2.0的Provider模式,转载需保留来源! 郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
2
3 Product p1 = Product.GetProduct("Coke");
4
5
6
7 // find out the cost
8
9 double cost = Store.GetProductPrice(p1);
10
11
12
13 // get it from the store
14
15 Store.RemoveProductFromStock(p1); // remove from inventory