2017年8月2日 星期三

[.NET] 流(Stream)的改變輸出入導向


衍生(Dervied)/聚合(Composited)流(Stream)的類別,具有流的輸出入能力,透過這個基礎介面,我們可以用來銜接不同類型的輸出入裝置,不需要實作任何轉換細節,對呼叫端而言只管將字串資料輸出入,可以把流看成某種程度的抽象化硬體



來實作一個像是火車轉轍器的輸出可導向物件:

  • 以Enum列舉可能的輸出裝置
  • 呼叫端(Caller)透過屬性Way來指定指定輸出對象
  • 呼叫端透過函式Write輸出
  • 在建構式(Constructor)將具體輸出對象起始化,由於都具備Stream(衍生/聚合),所以都能套上StreamWriter,之後裝在Dictionary內等候差遣



class outputSwitch
    {
        public enum routeSelections
        {
            PIPE,
            TCP,
            FILE,
        }

        public routeSelections Route
        {
            set
            {
               currentOutputWay = cachedInterfaces[value]; 
            }
        }
        private StreamWriter currentOutputWay = null;

        private Dictionary cachedInterfaces = new Dictionary();
        public void Write(String message)
        {
            Console.SetOut(currentOutputWay); // redirect
            Console.WriteLine(message); // write-in , common interface
        }

        public outputSwitch()
        {
           TcpClient __client  = new TcpClient(AddressFamily.InterNetwork);
           NamedPipeClientStream __npcs = new NamedPipeClientStream(".","test");
           FileStream __fs = new FileStream("./test.dat",FileMode.Append);

            //connection...
            __npcs.Connect();
            Task __task = __client.ConnectAsync("127.0.0.1",5001);
            while (!__task.IsCompleted);

            //preparing corresponding stream writers
            cachedInterfaces[routeSelections.TCP] = new StreamWriter(__client.GetStream());
            cachedInterfaces[routeSelections.PIPE] = new StreamWriter(__npcs);
            cachedInterfaces[routeSelections.FILE] = new StreamWriter(__fs);

        }
    }

呼叫端這邊僅認識輸出函式Write(),以及列舉型別而已,沒有直接耦合到輸出裝置(抽象化):


            outputSwitch mo = new outputSwitch();
            mo.Route = outputSwitch.routeSelections.FILE;
            mo.Write("Output to Filestream");
            mo.Route = outputSwitch.routeSelections.TCP;
            mo.Write("Output to Remote TCP Server");
            mo.Route = outputSwitch.routeSelections.PIPE;
            mo.Write("Output to PIPE for other process");


程式碼參考

沒有留言:

張貼留言