C#設計模式之訪問者模式

提高班14期郭倩_Ulrica發表於2018-06-08

前言

這不是一個特別常用的模式。不做太多介紹,以後學到再補充吧~

訪問者模式

表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

應用

適用於資料結構相對穩定的系統,它把資料結構和作用於結構上的操作之間的耦合解脫開,使得操作集合可以相對自由的演化。如果系統有比較穩定的資料結構,又有易於變化的演算法,使用訪問者模式比較合適
目的是要把處理從資料結構分析出來。

訪問者模式的能力和複雜性是把雙刃劍,只有當真正需要用它的時候,才考慮使用。不要誤用或濫用。

優點:增加新的操作容易
缺點:使增加新的資料結構變困難了

程式碼展示

抽象狀態類與抽象人類

//“狀態”的抽象類
    abstract class Action
    {
        //得到男人結論或反應
        public abstract void GetManConclusion(Man concreteElementA);

        //得到女人結論或反應
        public abstract void GetWomanConclusion(Woman concreteElementB);
    }

    //“人”的抽線類
    abstract class Person
    {
        //接受
        public abstract void Accept(Action visitor);//用來獲得“狀態”物件
    }

具體狀態類

//成功時
    class Success:Action 
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}時,背後多半有一個偉大的女人。",concreteElementA .GetType ().Name ,this.GetType ().Name );
        }

        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}時,背後多半有一個不成功的男人。", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    //失敗時
    class Failing : Action
    {
        public override void GetManConclusion(Man concreteElementA)
        {
            Console.WriteLine("{0}{1}時,背後多半有一個偉大的女人。", concreteElementA.GetType().Name, this.GetType().Name);
        }

        public override void GetWomanConclusion(Woman concreteElementB)
        {
            Console.WriteLine("{0}{1}時,背後多半有一個不成功的男人。", concreteElementB.GetType().Name, this.GetType().Name);
        }
    }

    //戀愛時。。。。
    //需要什麼狀態只要新增類即可,

具體人類:

//男人類
    class Man:Person 
    {
        public override void Accept(Action visitor)
        {
            visitor.GetManConclusion(this);
        }
    }

    //女人類
    class Woman:Person 
    {
        public override void Accept(Action visitor)
        {
            visitor.GetWomanConclusion(this);
        }
    }

物件結構:

//物件結構
    class ObjectStructure
    {
        private IList<Person> elements = new List<Person>();

        //增加
        public void Attach(Person element)
        {
            elements.Add(element);
        }

        //移除
        public void Detach(Person element)
        {
            elements.Remove(element);
        }

        //檢視顯示
        public void Display(Action visitor)//遍歷方法
        {
            foreach (Person e in elements)
            {
                e.Accept(visitor);
            }
        }
    }

客戶端程式碼:

 class Program
    {
        static void Main(string[] args)
        {
            ObjectStructure o = new ObjectStructure();
            o.Attach(new Man());    //在物件結構中加入要對比的男人和女人
            o.Attach(new Woman());

            Success v1 = new Success();     //檢視在各種狀態下,男人和女人的反應
            o.Display(v1);

            Failing v2 = new Failing();
            o.Display(v2);

            Console.Read();
        }
    }

效果圖:

訪問者

想要新增什麼狀態,只需新增類即可,也完美的詮釋了開放-封閉原則

後記

原來女人真的是個不講道理的動物呢,不管在什麼狀態下,女人都必須是要佔上風的~
小夥子們注意了~~

相關文章