2014年09月28日

ビジター

Visitor

訪問者のこと。
廃れることは無いとは思いますが、最近はあまり使われてないかも。

サンプルコード

Visitor Patternを使用しない例
    // 貯金箱
    class Moneybox
    {
        public int Amount { get; set; }
    }
    // 借金
    class Debt
    {
        public int Owed { get; set; }
    }
    // 財政状況
    class Finance 
    {
        List<Moneybox> _moneys = new List<Moneybox>();
        public List<Moneybox> MoneyBoxs { get { return _moneys ; } }

        List<Debt> _debts = new List<Debt>();
        public List<Debt> DebtList{ get { return _debts ; } }
    }

    class Tester
    {
        static void Main(string[] args)
        {
             Finance finance = new Finance();
             finance.MoneyBoxs.Add(new Moneybox{Amount = 5000});
             finance.MoneyBoxs.Add(new Moneybox{Amount = 3000});
             finance.DebtList.Add(new Owed{owed=2000});
 
             int sum;
             finance.MoneyBoxs.ForEach(mb ==> sum += mb.Amount);
             finance.DebtList.ForEach(debt==> sum -= debt.Owed);
         }
    }

上記をVisitor Patternを適用して書きお直します。
    // 訪問者
    interface IVisitor
    {
        void Visit(IVisitable visitable);
    }
    // 訪問される側
    interface IVisitable
    {
        void Accespt(IVisitor visitor);
    }

    class Moneybox : IVisitable
    {
        public int Amount { get; set; }

        public void Accespt(IVistor visitor)
        {
            visitor.Visit(this);
        }
    }
    class Debt : IVisitable 
    {
        public int Owed { get; set; }

        public void Accespt(IVistor visitor)
        {
            visitor.Visit(this);
        }
    }

    class Finance : IVisitable 
    {
        List<IVisitable> _assets = new List<IVisitable>();
        public List<IVisitable> Assets { get { return _assets; } }

        public void Accespt(IVisitor visitor)
        {
            _assets.ForEach(asset => asset.Accespt(visitor));
        }
    }
    class Visitor : IVisitor
    {
        public int Sum { get; set; }

        public void Visit(IVisitable visitable)
        {
            if(visitable is Moneybox)
            {
                Sum += ((Moneybox)visitable).Amount;
            }
            else if(visitable is Debt)
            {
                Sum -= ((Debt)visitable).Owed;
            }
        }
    }

    // 使用する側
    class Tester
    {
        static void Main(string[] args)
        {
            Finance finance = new Finance();
            finance.Assets.Add(new Moneybox { Amount = 5000 });
            finance.Assets.Add(new Moneybox { Amount = 3000 });
            finance.Assets.Add(new Debt { Owed = 2000 });

            // ここで計算していた分をVisitor側で行うよう修正
            Visitor visitor = new Visitor();
            finance.Accespt(visitor);

            int sum = visitor.Sum;
         }
    }

posted by RR at 10:32 | Comment(0) | デザインパターン | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。