2006年04月04日

Flyweight ― 同じものを共有して無駄をなくす

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



BigCharクラス
using System;
using System.IO;
using System.Text;

namespace Gushwell.DesignPatterns {
public class BigChar {
private char charname; // 文字の名前
private string fontdata; // 大きな文字を表現する文字列('#' '.' '\n'の列)

// コンストラクタ
public BigChar(char charname) {
this.charname = charname;
try {
StreamReader reader = new StreamReader("big" + charname + ".txt");
string line;
StringBuilder buf = new StringBuilder();
while ( ( line = reader.ReadLine() ) != null ) {
buf.Append(line);
buf.Append("\n");
}
reader.Close();
this.fontdata = buf.ToString();
} catch ( System.IO.IOException ) {
this.fontdata = charname + "?";
}
}

// 大きな文字を表示する
public virtual void Print() {
Console.Write(fontdata);
}
}
}


BigCharFactoryクラス
using System;
using System.Collections.Generic;

namespace Gushwell.DesignPatterns {
public sealed class BigCharFactory {
// すでに作ったBigCharのインスタンスを管理
private Dictionary<char, BigChar> pool = new Dictionary<char, BigChar>();

// Singletonパターン
private static readonly BigCharFactory singleton = new BigCharFactory();

// 唯一のインスタンスを得る
public static BigCharFactory Instance {
get { return singleton; }
}

// コンストラクタ
private BigCharFactory() {
}

// BigCharのインスタンス生成(共有)
public BigChar GetBigChar(char charname) {
lock ( this ) {
BigChar bc = null;
if ( pool.ContainsKey(charname) ) {
bc = pool[charname];
} else {
bc = new BigChar(charname); // ここでBigCharのインスタンスを生成
pool[charname] = bc;
}
return bc;
}
}
}
}


BigStringクラス
using System;

namespace Gushwell.DesignPatterns {
public class BigString {
private BigChar[] bigchars; // 「大きな文字」の配列

// コンストラクタ
public BigString(string str) {
bigchars = new BigChar[str.Length];
BigCharFactory factory = BigCharFactory.Instance;
for ( int i = 0; i < bigchars.Length; i++ ) {
bigchars[i] = factory.GetBigChar(str[i]);
}
}

// 表示
public virtual void Print() {
foreach ( BigChar bc in bigchars ) {
bc.Print();
}
}
}
}


Programクラス
using System;

namespace Gushwell.DesignPatterns {
public class Program {
public static void Main(string[] args) {
if ( args.Length == 0 ) {
Console.WriteLine("Usage: FlyWeightSample digits");
Console.WriteLine("Example: FlyWeightSample 1212123");
return;
}
BigString bs = new BigString(args[0]);
bs.Print();
}
}
}



 

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