かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

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();
        }
    }

}