最近在做一个轻量级CMS供客户站点使用。
根据客户的需求,需要以静态页方式提供用户浏览的页面,同时还要保留一个本份,支持“双远程”发布,即在一台远程发布服务器上保留存根,最终页面保存在文件服务器上供用户访问。
研究了半天,发现可以用策略模式和职责链模式相结合来实现这个处理逻辑(我估且称此为策略链模式)。
以下是策略链的根接口,其他接口从这上面继承:
1
namespace strategyChain
2
{
3
public interface IStrategy<T>
4
{
5
T Next{get;}
6
}
7
}
namespace strategyChain2
{3
public interface IStrategy<T>4
{5
T Next{get;}6
}7
}处理新闻的接口:
1
namespace strategyChain
2
{
3
public class News
4
{}
5![]()
6
public interface INewsStrategy : IStrategy<INewsStrategy>
7
{
8
void DoSomething(News news);
9
}
10
}
namespace strategyChain2
{3
public class News4
{}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
1
namespace strategyChain
2
{
3
public class LocalNewsStrategy : NewsStrategy
4
{
5
public LocalNewsStrate(INewsStrategy next) : base(next){}
6![]()
7
public override void Dosomething(News news)
8
{
9
localDo(news);
10
base.DoSomething(news);
11
}
12
}
13![]()
14
private void localDo(News news)
15
{
16
//todo:本地操作逻辑
17
}
18
}
namespace strategyChain2
{3
public class LocalNewsStrategy : NewsStrategy4
{5
public LocalNewsStrate(INewsStrategy next) : base(next){}6

7
public override void Dosomething(News news)8
{9
localDo(news);10
base.DoSomething(news);11
}12
}13

14
private void localDo(News news)15
{16
//todo:本地操作逻辑17
}18
} 1
namespace strategyChain
2
{
3
public class RemoteNewsStrategy : NewsStrategy
4
{
5
public RemoteNewsStrategy(INewsStrategy next)
6
:base(next){
7
8
}
9![]()
10
public override void DoSomething(News news)
11
{
12
remoteDo(news)
13
base.DoSomething(news);
14
}
15![]()
16
private void remoteDo(News news)
17
{
18
//执行远程逻辑
19
}
20
}
21
}
namespace strategyChain2
{3
public class RemoteNewsStrategy : NewsStrategy4
{5
public RemoteNewsStrategy(INewsStrategy next)6
:base(next){7
8
}9

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

16
private void remoteDo(News news)17
{18
//执行远程逻辑19
}20
}21
} 1
namespace strategyChain.SqlClient
2
{
3
public class SqlNewsStrategy : NewsStrategy
4
{
5
public SqlNewsStrategy(INewsStrategy next):base(next){}
6![]()
7
public override void DoSomething(News news)
8
{
9
sqlDo(news);
10
base.DoSomething(news);
11
}
12![]()
13
private void sqlDo(News news)
14
{
15
//执行数据库逻辑
16
}
17
}
18
}
namespace strategyChain.SqlClient2
{3
public class SqlNewsStrategy : NewsStrategy4
{5
public SqlNewsStrategy(INewsStrategy next):base(next){}6

7
public override void DoSomething(News news)8
{9
sqlDo(news);10
base.DoSomething(news);11
}12

13
private 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)
}
}
}写完了这个抽象类以后,再在最后一个结点处继承该抽象类:
1
namespace strategyChain.SqlClient
2
{
3
public class SqlNewsProvider : NewsProvider
4
{
5
//这个类只要将sqlNewsStrategy加入到策略链就行了,其他的什么都不用做.
6
public SqlNewsProvider()
7
{
8
strategy = new SqlNewsStrategy(strategy);
9
}
10
}
11
}
namespace strategyChain.SqlClient2
{3
public class SqlNewsProvider : NewsProvider4
{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
浙公网安备 33010602011771号