2014年09月04日

デコレーター

Decorator

飾るという意味。
外側にどんどん飾りつけを増やしても、元のAPI(シグネチャ)は変わらない。


Sample Code



    // インタフェースとなる定義
    public abstract class Component
    {
        public abstract void Write();
    }
    // インタフェース(抽象クラス)を継承した具象クラス
    public class ConcreteComponent : Component
    {
        public override void Write()
        {
            Console.WriteLine("Original message");
        }
    }
    // デコレータその1(インタフェースを継承しているところがミソ)
    public class Decorator1 : Component
    {
        public Component Component { get; set; }
        public override void Write()
        {
            Console.WriteLine("--------------");
            Component.Write();
            Console.WriteLine("--------------");
        }
    }
    // こちらもデコレータその2
    public class Decorator2 : Component
    {
        public Component Component { get; set; }
        public override void Write()
        {
            Console.WriteLine("##############");
            Component.Write();
            Console.WriteLine("##############");
        }
    }
これらを使う方のコード
    class Tester
    {
        static void Main(string[] args)
        {
           // オリジナルの出力処理
            Component comp = new ConcreteComponent();
            comp.Write();

            // デコレータで飾った出力
            comp = new Decorator1() { Component = comp };
            comp.Write();

           // デコレートの上塗り
            comp = new Decorator2() { Component = comp };
            comp.Write();
        }
    }

別案

最近は上記のような実装する機会が殆どなくなった。
匿名メソッドとかラムダ式が出てきたから。
インタフェースとか継承元クラスとか定義するのが面倒臭い。
同様のことが簡単に実装できるしね。
こんな感じ

        static void Decoreate(Action action)
        {
            Console.WriteLine("--------------");
            action();
            Console.WriteLine("--------------");
        }

        static void TryCatch(Action action)
        {
            try
            {
                action();
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        public bool AspectLog(Func<bool> func)
        {
            var sw = new Stopwatch();
            sw.Start();
            var ret = func();
            sw.Stop();
            Debug.WriteLine(sw.ElapsedMilliseconds);
            return ret;
        }
posted by RR at 00:00 | Comment(0) | デザインパターン | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

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