2006年04月14日

Proxy ― 必要になってから作る

  
ここに掲載したコードは、『増補改訂版Java言語で学ぶデザインパターン入門 / 結城 浩(著)』に掲載されているサンプルコードをC#に移植したものです。移植後のコードの公開に関しては、結城氏の了解を得ています。
※当ソースは、Visual C# 2005 Express Editionで動作を確認しています。



IPrintableインターフェース
using System;

namespace Gushwell.DesignPatterns {
public interface IPrintable {
void SetPrinterName(string name); // 名前の設定
string GetPrinterName(); // 名前の取得
void Print(string string_Renamed); // 文字列表示(プリントアウト)
}
}



Printerクラス
using System;

namespace Gushwell.DesignPatterns {
public class Printer : IPrintable {
private string name;

// コンストラクタ
public Printer() {
HeavyJob("Printerのインスタンスを生成中");
}

// コンストラクタ
public Printer(string name) {
this.name = name;
HeavyJob("Printerのインスタンス(" + name + ")を生成中");
}

// 名前の設定
public virtual void SetPrinterName(string name) {
this.name = name;
}

// 名前の取得
public virtual string GetPrinterName() {
return name;
}

// 名前付きで表示
public virtual void Print(string string_Renamed) {
Console.WriteLine("=== " + name + " ===");
Console.WriteLine(string_Renamed);
}

// 重い作業(のつもり)
private void HeavyJob(string msg) {
Console.Write(msg);
for (int i = 0; i < 5; i++) {
System.Threading.Thread.Sleep(1000);
Console.Write(".");
}
Console.WriteLine("完了。");
}
}
}



PrinterProxyクラス
using System;

namespace Gushwell.DesignPatterns {
public class PrinterProxy : IPrintable {
private string name; // 名前
private Printer real; // 「本人」

public PrinterProxy() {
}

// コンストラクタ
public PrinterProxy(string name) {
this.name = name;
}

// 名前の設定
public virtual void SetPrinterName(string name) {
lock (this) {
if (real != null) {
real.SetPrinterName(name); // 「本人」にも設定する
}
this.name = name;
}
}

// 名前の取得
public virtual string GetPrinterName() {
return name;
}

// 表示
public virtual void Print(string string_Renamed) {
Realize();
real.Print(string_Renamed);
}

// 「本人」を生成
private void Realize() {
lock (this) {
if (real == null) {
real = new Printer(name);
}
}
}
}
}



Programクラス
using System;

namespace Gushwell.DesignPatterns {
public class Program {

[STAThread]
public static void Main(string[] args) {
IPrintable p = new PrinterProxy("Alice");
Console.WriteLine("名前は現在" + p.GetPrinterName() + "です。");
p.SetPrinterName("Bob");
Console.WriteLine("名前は現在" + p.GetPrinterName() + "です。");
p.Print("Hello, world.");
}
}
}



 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/50421000