前回の生成に関するパターンに引き続いて構造に関するパターンをやってみようと思います。前回と同様参考にしてるサイトは以下のサイトです。
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(); } } }