BlogEngine学习(1)--Provider模式
2011-12-09 17:14 hedalixin 阅读(331) 评论(0) 收藏 举报首先什么是Provider模式?Provider是由两个设计模式融合而来的:策略模式+抽象工厂模式。这两个模式具体的介绍我在这里就不多说了,网上一搜一大把。provider模式的作用是为一个API进行定义和实现的分离。这样就通过核心功能的灵活性和易于修改的特点使得API具有灵活性。通俗一点来说就是实现了定义和实现的分离,最终效果就是不需要更改代码即可实现程序不同逻辑的改变。
在BlogEngine中,provider模式被应用于提供不同的数据的持久化。为了保证解压后就能使用默认采用的是xmlProvider。本文研究的重点就是了解这个Provider模式,并知道BlogEngine如何通过provider模式使得不同数据持久化方式之间的灵活切换。
先来看看我实现的Provider模式例子的关系图:
上图中的各个类已经表明了作用。下面我还会在讲解代码的过程中具体解释这些类的。需要说明的是Provider模式不仅仅是可以为系统提供不同的数据持久方式,在业务逻辑中也同样可以提供不同的方式,不一定要拘泥于数据库这块。
先来编写BlogProvider和BlogProviderCollection 。这个类是个抽象类,定义了需要实现的抽象方法以便于子类实现。为了演示的方便,这里我就写了一个方法:
namespace ProviderTest
{
public abstract class BlogProvider:ProviderBase
{
public abstract string GetPage();
}
public class BlogProviderCollection : ProviderCollection
{
public new BlogProvider this[string name]
{
get { return (BlogProvider)base[name]; }
}
public override void Add(ProviderBase provider)
{
if (provider == null)
throw new ArgumentNullException("provider");
if (!(provider is BlogProvider))
throw new ArgumentException
("Invalid provider type", "provider");
base.Add(provider);
}
}
}
从上面可以看到BlogProvider类继承了ProviderBase类。这个类是.net为我们提供的,里面定义了provider操作的一些“规范”。BlogProviderCollection类用于管理Provider集合,它继承于ProviderCollection类,这个类也是系统提供的,简化了provider操作的步骤。在BlogService中我们会用到这个类来初始化provider集合信息。
下面我再编写DbBlogProvider和XmlBlogProvider类。这两个类继承了BlogProvider类。这是策略模式里面将不同的操作封装起来,使得具体方法的变化不会影响到使用方法的客户。
public class DbBlogProvider :BlogProvider
{
public override string GetPage()
{
return "GetPage by db";
}
//重写BlogBase里面的Initialize方法
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (string.IsNullOrEmpty(name))
name = "blogProvider";
if (null == config)
throw new ArgumentException("config参数不能为null");
base.Initialize(name, config);
}
}
public class XmlBlogProvider:BlogProvider
{
public override string GetPage()
{
return "GetPage by XML";
}
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
if (string.IsNullOrEmpty(name))
name = "blogProvider";
if (null == config)
throw new ArgumentException("config参数不能为null");
base.Initialize(name, config);
}
}
接着再看BlogProviderConfigureSection这个类,这个类可以看成一个管理配置文件中节点的类。后面在BlogService中获得配置文件的信息就靠它了。在这个类中的属性上面采用了Attribute的方式声明值,具体里面的值可以通过反射得到。
public class BlogProviderConfigureSection:ConfigurationSection
{
[ConfigurationProperty("providers")]
public ProviderSettingsCollection Providers
{
get { return (ProviderSettingsCollection)base["providers"]; }
}
[StringValidator(MinLength = 1)]
[ConfigurationProperty("defaultProvider", DefaultValue = "XmlBlogProvider")]
public string DefaultProvider
{
get { return (string)base["defaultProvider"]; }
set { base["defaultProvider"] = value; }
}
}
最后就是我们BlogService类了。在BlogEngine中这个类是业务层和表现层的纽带,表现层通过这个方法调用业务层。也可以这样说,这个类实现了业务层的一个统一的访问接口,这样使得代码层次就比较清晰了,可以理解为装饰模式。代码如下:
private BlogProvider _provider;
private BlogProviderCollection _providerCollection;
public BlogService()
{
LoadProvider();
}
private void LoadProvider()
{
BlogProviderConfigureSection config = null;
if (_provider==null)
{
//获得blogProvider节点信息
config = (BlogProviderConfigureSection)ConfigurationManager.GetSection("blogProvider");
_providerCollection = new BlogProviderCollection();
//下面这个方法是系统提供的,位于System.web下。如果编写的是form程序则需要自己实现这个providhelper
//有兴趣的 可以查看一下他的源码
ProvidersHelper.InstantiateProviders(config.Providers, _providerCollection, typeof(BlogProvider));
//上面那个方法已经加载了providerCollection,这里我们只要DefaultProvider的provider即可
_provider = _providerCollection[config.DefaultProvider];
}
}
public string GetPage()
{
return _provider.GetPage();
}
最后不要忘了配置一下web.config,不然程序可不知道用哪个方法。在configsections里面添加:
<section name="blogProvider" type="ProviderTest.BlogProviderConfigureSection,ProviderTest" />
然后在configuration下增加:
<blogProvider defaultProvider="XmlBlogProvider">
<providers>
<add name="XmlBlogProvider" type="ProviderTest.XmlBlogProvider"/>
<add name="DbBlogProvider" type="ProviderTest.DbBlogProvider"/>
</providers>
</blogProvider>
最后写一个页面简单的调用一下就可以看到结果了。当你设置改变defaultProvider这个属性值的时候,浏览器简单刷新一下就已经得到了你更改后的结果。
BlogEngine中实现provider的方式基本上和上面讲的差不多。有点区别的地方在于BlogEngine的XmlProvider中,采用了partial关键字定义了XmlProvider类,这样就实现了不同功能的分离,结构更加清晰。
原文地址:http://www.cnblogs.com/qianlifeng/archive/2010/12/07/1899343.html


 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号