C#设计模式---PipeLine

一、概述

顾名思义,管道模式就像一条管道把多个对象连接起来,整体看起来就像若干个阀门嵌套在管道中,而处理逻辑就放在阀门上,如下图,需要处理的对象进入管道后,分别经过阀门一、阀门二、阀门三、阀门四,每个阀门都会对进入的对象进行一些逻辑处理,经过一层层的处理后从管道尾处理,此时的对象就是已完成处理的目标对象。

二、主要角色

  • 阀门 处理数据的节点
  • 管道 组织各个阀门
  • 客户端 构造管道,并调用

三、实现Demo

using System;
/// <summary>
///PipeLine模式的几个角色
///阀门 处理数据的节点
///管道 组织各个阀门
///客户端 构造管道,并调用
/// </summary>
namespace DesignMode_PileLine
{
    //阀门接口
    public interface IValve
    {
        IValve GetNext();
        void SetNext(IValve v);
        void Invoke(string s);
    }
    //管道接口
    public interface IPipeLine
    {
        IValve GetFirst();
        IValve GetBasic();
        void SetBasic(IValve v);
        void AddValve(IValve v);
    }
    /// <summary>
    ///尾阀门
    /// </summary>
    public class BasicValve:IValve
    {
        private IValve _nextValve;
        public IValve GetNext()
        {
            return _nextValve;
        }
        public void SetNext(IValve v)
        {
            _nextValve = v;
        }
        public void Invoke(string s)
        {
            string org = s;
            Console.WriteLine($"Basic valve invoked! Will replace a with b");
            s = s.Replace('a', 'b');
            Console.WriteLine($"Basic valved handled: {org} => {s}");
        }
    }
    /// <summary>
    /// 普通阀门
    /// </summary>
    /// 
    public class FirstValve : IValve
    {
        private IValve _nextValve;
        public IValve GetNext()
        {
            return _nextValve;
        }
        public void SetNext(IValve v)
        {
            _nextValve = v;
        }
        public void Invoke(string s)
        {
            string org = s;
            Console.WriteLine($"First valve invoked! Will replace 1 with 2");
            s = s.Replace('1', '2');
            Console.WriteLine($"First valved handled: {org} => {s}");

            GetNext()?.Invoke(s);//将数据传递到下一个阀门
        }
    }
    public class SecondValve : IValve
    {
        private IValve _nextValve;
        public IValve GetNext()
        {
            return _nextValve;
        }
        public void SetNext(IValve v)
        {
            _nextValve = v;
        }
        public void Invoke(string s)
        {
            string org = s;
            Console.WriteLine($"Second valve invoked! Will replace 5 with 6");
            s = s.Replace('5', '6');
            Console.WriteLine($"Second valved handled: {org} => {s}");

            GetNext()?.Invoke(s);//将数据传递到下一个阀门
        }
    }

    public class StandardPipeLine :IPipeLine
    {
    
        private IValve _firstValve;
        private IValve _basicValve;
        public IValve GetFirst()
        {
            return _firstValve;
        }
        public IValve GetBasic()
        {
            return _basicValve;
        }
        public void SetBasic(IValve v)
        {
            _basicValve = v;
        }
        public void AddValve(IValve v)
        {
            if(_firstValve == null)
            {
                _firstValve = v;
                v.SetNext(_basicValve);
            }
            else
            {
                IValve current = _firstValve;
                while(current != null)
                {
                    if (current.GetNext() == _basicValve)
                    {
                        current.SetNext(v);
                        v.SetNext(_basicValve);
                        break;
                    }
                    current = current.GetNext();
                }
            }
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            string s = "1123wsa346yt4543s2156ac";
            StandardPipeLine pipeLine = new StandardPipeLine();
            BasicValve basicValve = new BasicValve();
            FirstValve firstValve = new FirstValve();
            SecondValve secondValve = new SecondValve();
            pipeLine.SetBasic(basicValve);
            pipeLine.AddValve(firstValve);
            pipeLine.AddValve(secondValve);
            pipeLine.GetFirst().Invoke(s);

        }
    }   
}

注:
阀门的实现分两种,即普通阀门和尾阀门。普通阀门在处理完自己的事情之后,必须调用GetNext.invoke(s)方法交给下一个阀门处理;而尾阀门不用调用这个方法,因为它是结束的那个阀门。

PipeLine实现类的主要逻辑在AddValve,它持有一个头阀门和一个尾阀门,它按照添加阀门顺序的方式构造阀门链表,按照队列的形式,先添加的先调用

猜你喜欢

转载自www.cnblogs.com/3xiaolonglong/p/9984107.html