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,它持有一個頭閥門和一個尾閥門,它按照添加閥門順序的方式構造閥門鏈表,按照隊列的形式,先添加的先調用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM