最近在做一个轻量级CMS供客户站点使用。

根据客户的需求,需要以静态页方式提供用户浏览的页面,同时还要保留一个本份,支持“双远程”发布,即在一台远程发布服务器上保留存根,最终页面保存在文件服务器上供用户访问。

研究了半天,发现可以用策略模式和职责链模式相结合来实现这个处理逻辑(我估且称此为策略链模式)。

以下是策略链的根接口,其他接口从这上面继承:

1namespace strategyChain
2{
3 public interface IStrategy<T>
4{
5 T Next{get;}
6}

7}

处理新闻的接口:
 1namespace strategyChain
 2{
 3 public class News
 4{}
 5
 6 public interface INewsStrategy : IStrategy<INewsStrategy>
 7{
 8  void DoSomething(News news);
 9}

10}

然后写一个抽象类来实现该接口:NewsStrategy

namespace strategyChain
{
 
public abstract class NewsStratey : INewsStrategy
{
protected INewsStrategy next;
 
public NewsStrate(INewsStrategy next)
{
 
this.next = next;
}


public virtual void DoSomething(News news)
{
if(next != null)
{
 next.DoSomething();
}

}

}

}

为了满足顾客的要求,写了三个类来继承NewsStrategy: LocalNewsStrategy,RemoteNewsStrategy,SqlNewsStrategy

 1namespace strategyChain
 2{
 3 public class LocalNewsStrategy : NewsStrategy
 4{
 5  public LocalNewsStrate(INewsStrategy next) : base(next){}
 6
 7public override void Dosomething(News news)
 8{
 9  localDo(news);
10  base.DoSomething(news);
11}

12}

13
14private void localDo(News news)
15{
16//todo:本地操作逻辑
17}

18}

 1namespace strategyChain
 2{
 3 public class RemoteNewsStrategy : NewsStrategy
 4{
 5 public RemoteNewsStrategy(INewsStrategy next)
 6:base(next){
 7 
 8}

 9
10public override void DoSomething(News news)
11{
12 remoteDo(news)
13 base.DoSomething(news);
14}

15
16private void remoteDo(News news)
17{
18 //执行远程逻辑
19}

20}

21}

 1namespace strategyChain.SqlClient
 2{
 3 public class SqlNewsStrategy : NewsStrategy
 4{
 5 public SqlNewsStrategy(INewsStrategy next):base(next){}
 6
 7public override void DoSomething(News news)
 8{
 9 sqlDo(news);
10 base.DoSomething(news);
11}

12
13private void sqlDo(News news)
14{
15 //执行数据库逻辑
16}

17}

18}

把这个写完了以后,创建一个NewsProvider类,来根据用户定义配置稿件的操作逻辑,配置完以后应用程序利用工厂方法,在运行时得到一个NewsProvider,来执行策略链。工厂方法在这里就不写了,写一个NewsProvider的实现。

namespace strategyChain
{
 
public abstract class NewsProvider
{
 
protected INewsStrategy strategy;

public NewsProvider()
{
 strategy 
= new RemoteNewsStrategy(null);
 strategy 
= new LocalNewsStrategy(strategy)
}


public void DoSomething(News news)
{
 strategy.DoSomething(news)
}

}

}

写完了这个抽象类以后,再在最后一个结点处继承该抽象类:
 1namespace strategyChain.SqlClient
 2{
 3 public class SqlNewsProvider : NewsProvider
 4{
 5//这个类只要将sqlNewsStrategy加入到策略链就行了,其他的什么都不用做.
 6 public SqlNewsProvider()
 7{
 8 strategy = new SqlNewsStrategy(strategy);
 9}

10}

11}

最后只需要在配置文件中指定 NewsProvider = "SqlNewsProvider"即可,真正的运行时代码将是
News news = null;
//实现news
NewsProvider provider = NewsFactory.GetNewsProvider();
provider.DoSomething(news);
 posted on 2008-06-04 12:01  吴辉军  阅读(722)  评论(0编辑  收藏  举报