かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

C# 4.0で実装するデザインパターン「その2 構造に関するパターン1」

前回の生成に関するパターンに引き続いて構造に関するパターンをやってみようと思います。前回と同様参考にしてるサイトは以下のサイトです。

Adapterパターン

Adapterパターンは、インターフェースが違うものを同じように扱えるようにしようぜ!っていうノリのパターンです。何のことはない、インターフェースが同じになるようにクラスを間に1枚かませるだけですね。

これも、実装は大してJavaと変わりありませんが、なんとなく実装してみました。

// PresentationCore, PresentationFramework, 
// WindowsBase, System.Xamlを参照に追加すること
namespace Okazuki.GoFPatterns.Adapter
{
    using System;
    using System.Windows;

    class Program
    {
        static Target Create(string str)
        {
            if (str == "Target")
            {
                return new Target();
            }
            if (str == "Adapter")
            {
                return new Adapter();
            }
            throw new ArgumentException();
        }

        [STAThread]
        static void Main(string[] args)
        {
            var target1 = Create("Target");
            var target2 = Create("Adapter"); // クライアントにはTargetとして渡す

            target1.Operation();
            target2.Operation(); // Windowの表示をTargetのインターフェースに合わせれた
        }
    }

    class Target
    {
        public virtual void Operation()
        {
            Console.WriteLine("Hello Design Pattern");
        }
    }

    // WindowのShowDialogをTargetクラスのOperationという形で呼べるようにする
    class Adapter : Target
    {
        private Window adaptee = new Window 
        { 
            Title = "Adapter Sample",
            Content = "Hello Design Pattern",
            Width = 150,
            Height = 150
        };

        public override void Operation()
        {
            adaptee.ShowDialog();
        }
    }
}

Bridgeパターン

何だか、構造に関するパターンを書いてて思ってきたのですが、構造を定義するパターンなんだから、C#4.0で書いてもさして変わりはないんじゃないんだろうか・・・。と思ってきたところです。


Bridgeパターンは機能と実装を分離するパターンとあります。ぴんとこないですよね?私はきません。
機能と実装が何パターンかあるときに、1つのクラスに機能も実装も詰め込むと機能x実装の数だけ継承関係ができるのを分離して機能+実装にしてしまおうというパターンだと私は思ってます。

ということで、さくっと実装しました。

// PresentationCore, PresentationFramework, WindowsBase
// System.Xamlを参照に追加すること
namespace Okazuki.GoFPatterns.Bridge
{
    using System;
    using System.Windows;

    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            var abstraction = new Abstraction("A");
            abstraction.Operation();

            abstraction = new Abstraction("B");
            abstraction.Operation();
        }
    }

    class Abstraction
    {
        private Implementor imp;

        public Abstraction(string sw)
        {
            if (sw == "A")
            {
                this.imp = new ImplementorA();
            }
            if (sw == "B")
            {
                this.imp = new ImplementorB();
            }
        }

        public void Operation()
        {
            this.imp.OperationImp();
        }
    }

    abstract class Implementor
    {
        public abstract void OperationImp();
    }

    class ImplementorA : Implementor
    {
        public override void OperationImp()
        {
            Console.WriteLine("Call ImplementorA::OperationImp()");
        }
    }

    class ImplementorB : Implementor
    {
        Window window = new Window
        {
            Title = "BridgeSample",
            Content = "Call ImplementorB::OperationImp()",
            Height = 150,
            Width = 250
        };

        public override void OperationImp()
        {
            window.ShowDialog();
        }
    }

}