Created
February 17, 2014 15:16
-
-
Save EsProgram/9052450 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 以下のコードは | |
* アラン・シャロウェイ,ジェームズ・R・トロット:著 / 村上 雅章:訳 / (2005) / 『デザインパターンとともに学ぶ オブジェクト指向のこころ』 / 株式会社ピアソン・エデュケーション | |
* より、自分なりにC#用に改変させていただいたコードです | |
*/ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
class DecoratorTest | |
{ | |
static void Main(string[] args) | |
{ | |
Factory myFactory = new Factory(); | |
Component myComponent = myFactory.GetComponent1(); | |
myComponent.PrintTicket(); | |
Console.WriteLine(); | |
myComponent = myFactory.GetComponent2(); | |
myComponent.PrintTicket(); | |
} | |
} | |
abstract class Component | |
{ | |
/// <summary> | |
/// 伝票を印字する | |
/// </summary> | |
abstract public void PrintTicket(); | |
} | |
class SalesTicket : Component | |
{ | |
public override void PrintTicket() | |
{ | |
//ここに伝票の内約が表示されます | |
Console.WriteLine("これは伝票の内約です"); | |
} | |
} | |
abstract class TicketDecorator : Component | |
{ | |
//再帰的に修飾機能を格納し、メイン機能は最後に1回格納する | |
Component myComponent; | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
/// <param name="c">Componentを継承する具象クラス</param> | |
public TicketDecorator(Component c) | |
{ | |
myComponent = c; | |
} | |
/// <summary> | |
/// 保持しているComponentがnullでなければ | |
/// プリントアウトするメソッド | |
/// </summary> | |
public void CallTrailer() | |
{ | |
if(myComponent != null) | |
myComponent.PrintTicket(); | |
} | |
} | |
class Header1 : TicketDecorator | |
{ | |
/// <summary> | |
/// myComponentはprivateなのでこのクラス内からではアクセス不可 | |
/// よって、スーパークラスのコンストラクタを呼び出す | |
/// | |
/// privateなメンバではあるが、このクラス内に複製されているものとして扱える | |
/// スーパークラスのmyComponentを操作しているわけではないので注意 | |
/// | |
/// 特にこのクラスでのみ特別にスーパークラスのメンバを扱わない場合は | |
/// protectedとして継承するよりはprivateのまま継承して、初期化させてしまう方が | |
/// このクラス内で下手に変更してしまう危険性がなくなるため、この手法を利用する | |
/// </summary> | |
/// <param name="c">Componentを継承する具象クラス</param> | |
public Header1(Component c) : base(c) { } | |
public override void PrintTicket() | |
{ | |
//メソッドの呼び出し順に気をつけましょう | |
//まずはヘッダなので先に出力します(自分の出力) | |
//その後、保持しているComponentの出力メソッドを呼び出すようにしています | |
//自分の出力 | |
Console.WriteLine("ヘッダ1を出力しました"); | |
//保持しているComponentの出力メソッドを呼び出す | |
CallTrailer(); | |
} | |
} | |
class Header2 : TicketDecorator | |
{ | |
public Header2(Component c) : base(c) { } | |
public override void PrintTicket() | |
{ | |
Console.WriteLine("ヘッダ2を出力しました"); | |
CallTrailer(); | |
} | |
} | |
class Footer1 : TicketDecorator | |
{ | |
public Footer1(Component c) : base(c) { } | |
public override void PrintTicket() | |
{ | |
//ここでも呼び出し順に注意です | |
//先にComponentへの参照から出力させ | |
//その後、自分の出力をします | |
CallTrailer(); | |
Console.WriteLine("フッタ1を出力しました"); | |
} | |
} | |
class Footer2 : TicketDecorator | |
{ | |
public Footer2(Component c) : base(c) { } | |
public override void PrintTicket() | |
{ | |
CallTrailer(); | |
Console.WriteLine("フッタ2を出力しました"); | |
} | |
} | |
class Factory | |
{ | |
/// <summary> | |
/// ヘッダ1 | |
/// ヘッダ2 | |
/// 内約 | |
/// フッタ1 | |
/// フッタ2 | |
/// を印字する | |
/// </summary> | |
/// <returns>印字に必要なオブジェクト群</returns> | |
public Component GetComponent1() | |
{ | |
return new Header1(new Header2(new Footer2(new Footer1(new SalesTicket())))); | |
/*以下も、上記と同じ意味を持つ*/ | |
//Component component; | |
//component = new SalesTicket(); | |
//component = new Footer1(component); | |
//component = new Footer2(component); | |
//component = new Header2(component); | |
//component = new Header1(component); | |
//return component; | |
} | |
/// <summary> | |
/// ヘッダ1 | |
/// 内約 | |
/// フッタ1 | |
/// フッタ2 | |
/// を印字する | |
/// </summary> | |
/// <returns>印字に必要なオブジェクト群</returns> | |
public Component GetComponent2() | |
{ | |
return new Header1(new Footer2(new Footer1(new SalesTicket()))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment