[設計模式練習]訪問者模式

[設計模式練習]訪問者模式

將買賣行為用訪問者模式設計

固定的類別:買方及賣方

變動的類別:商品(包括食衣住以及後續擴充)

類別圖

Visitor

物件檔定義

using System.Collections.Generic;
using System.Text;

namespace DesignModelTest.訪問者
{
    /// <summary>
    /// visitor類別:商品
    /// </summary>
    abstract class Goods
    {
        public abstract void GetSellerReaction(Seller seller);//得到concreteelement1的反應
        public abstract void GetBuyerReaction(Buyer buyer);//得到concreteelement2的反應
    }
    abstract class TradeMember
    {
        public abstract void Accept(Goods visitor);
    }
    /// <summary>
    /// concretevistor1類別:食物
    /// </summary>
    class Food : Goods
    {
        public override void GetBuyerReaction(Buyer buyer)
        {
            Console.WriteLine("{0}買商品{1}", buyer.GetType().Name, this.GetType().Name);
        }
        public override void GetSellerReaction(Seller seller)
        {
            Console.WriteLine("{0}賣商品{1}", seller.GetType().Name, this.GetType().Name);
        }
    }
    /// <summary>
    /// concretevistor2類別:衣服
    /// </summary>
    class Clothes : Goods
    {
        public override void GetBuyerReaction(Buyer buyer)
        {
            Console.WriteLine("{0}買商品{1}", buyer.GetType().Name, this.GetType().Name);
        }
        public override void GetSellerReaction(Seller seller)
        {
            Console.WriteLine("{0}賣商品{1}", seller.GetType().Name, this.GetType().Name);
        }
    }
    /// <summary>
    /// concretevistor3類別:房屋
    /// </summary>
    class House : Goods
    {
        public override void GetBuyerReaction(Buyer buyer)
        {
            Console.WriteLine("{0}買商品{1}", buyer.GetType().Name, this.GetType().Name);
        }
        public override void GetSellerReaction(Seller seller)
        {
            Console.WriteLine("{0}賣商品{1}", seller.GetType().Name, this.GetType().Name);
        }
    }
    /// <summary>
    /// concreteelement2類別:買方
    /// </summary>
    class Seller : TradeMember
    {
        public override void Accept(Goods visitor)
        {
            visitor.GetSellerReaction(this);
        }
    }
    /// <summary>
    /// concreteelement1類別:賣方
    /// </summary>
    class Buyer : TradeMember
    {
        public override void Accept(Goods visitor)
        {
            visitor.GetBuyerReaction(this);
        }
    }
    /// <summary>
    /// 提供介面以允許訪問者存取他的元素
    /// </summary>
    class ObjectStructure
    {
        private List<TradeMember> trademembers = new List<TradeMember>();
        /// <summary>
        /// 增加買方或賣方.
        /// </summary>
        /// <param name="trademember">The trademember.</param>
        public void Attach(TradeMember trademember)
        {
            trademembers.Add(trademember);
        }
        /// <summary>
        /// 移除買方或賣方.
        /// </summary>
        /// <param name="trademember">The trademember.</param>
        public void Detach(TradeMember trademember)
        {
            trademembers.Remove(trademember);
        }
        /// <summary>
        /// 實現行為.
        /// </summary>
        /// <param name="goods">The goods.</param>
        public void Display(Goods goods)
        {
            foreach (TradeMember e in trademembers)
            {
                e.Accept(goods);
            }
        }
    }
}

用戶端程式碼

            DesignModelTest.訪問者.ObjectStructure o = new DesignModelTest.訪問者.ObjectStructure();
            DesignModelTest.訪問者.TradeMember seller = new DesignModelTest.訪問者.Seller();
            DesignModelTest.訪問者.TradeMember buyer = new DesignModelTest.訪問者.Buyer();
            //物件結構要把所有相關的ConcreteElement類別都加入
            o.Attach(seller);
            o.Attach(buyer);
            //商品為食物的反應
            DesignModelTest.訪問者.Food food = new DesignModelTest.訪問者.Food();
            o.Display(food);
            //商品為衣服的反應
            DesignModelTest.訪問者.Clothes clothes = new DesignModelTest.訪問者.Clothes();
            o.Display(clothes);
            //商品為房屋的反應
            DesignModelTest.訪問者.House house = new DesignModelTest.訪問者.House();
            o.Display(house);
            Console.Read();
            #endregion

輸出結果

pic1