zoukankan      html  css  js  c++  java
  • 策略模式和职责链模式在CMS中的应用

    最近在做一个轻量级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);
  • 相关阅读:
    openstack 之Queen版本安装完成创建实例状态报错为ERROR
    重启nova-scheduler服务,报错Login was refused using authentication mechanism AMQPLAIN
    Failed to contact the endpoint at http://controller:35357/ for discovery. Fallback to using that endpoint as the base url.
    在centos系统的/etc/hosts添加了 当前主机的 ‘ NAT分配的IP controller’,RabbitMQ添加用户报错。
    一对简单的IPV6 SOCKET代码
    字节转换函数
    libevent笔记6:ssl bufferevent
    libevent笔记5:水位watermarks
    libevent笔记4:Filter_bufferevent过滤器
    libevent笔记3:evbuffer
  • 原文地址:https://www.cnblogs.com/lvwuhuijun/p/1213376.html
Copyright © 2011-2022 走看看