Flyweight パターン
* 生成済みのオブジェクトをできるだけ再利用(共有)し、 無駄なオブジェクト生成処理(メモリ使用)を防止するパターン
登場人物
Flyweight
* 多くのオブジェクトを生成され得る可能性のあるクラス
FlyweightFactory
★このクラスがキモ★* 「Flyweight」を生成管理する工場 * 「Flyweight」のオブジェクトが必要な場合は、この工場経由で取得 * 生成した「Flyweight」オブジェクトをMapなどで貯めて(プール)おく * 共有可能なオブジェクトが要求された場合は、プールから返却
Client
* 利用者
サンプル
Logger.java
* Flyweightimport java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; public class Logger { private String logFilePath; private PrintWriter printWriter = null; public Logger(String logFilePath) throws UnsupportedEncodingException, FileNotFoundException { this.logFilePath = logFilePath; this.printWriter = new PrintWriter( new OutputStreamWriter( new FileOutputStream( new File(logFilePath)), "UTF-8")); } @SuppressWarnings("unused") private Logger() { } public String getLogFilePath() { return this.logFilePath; } public void writeLog(String content) { this.printWriter.println(content); this.printWriter.flush(); } public void close() { if (this.printWriter != null) { this.printWriter.close(); } } }
LoggerFactory.java
* FlyweightFactoryimport java.io.FileNotFoundException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; public class LoggerFactory { private Map<String, Logger> loggers = null; public LoggerFactory() { this.loggers = new HashMap<String, Logger>(); } /** マルチスレッドを考慮し、「Synchronized」修飾子を付け、同期化さる。 * @throws FileNotFoundException * @throws UnsupportedEncodingException */ public synchronized Logger createInstance(String filePath) throws UnsupportedEncodingException, FileNotFoundException{ Logger logger = this.loggers.get(filePath); if (logger == null){ logger = new Logger(filePath); this.loggers.put(filePath, logger); } return logger; } public void finalize() { for(Logger logger : loggers.values()) { logger.close(); } } }
Main.java
* Clientimport java.io.FileNotFoundException; import java.io.UnsupportedEncodingException; public class Main { public static void main(String[] args) { LoggerFactory loggerFactory = new LoggerFactory(); try { Logger logger1 = loggerFactory.createInstance("test1.txt"); Logger logger2 = loggerFactory.createInstance("test2.txt"); logger1.writeLog("123"); logger1.writeLog("456"); logger2.writeLog("abc"); logger2.writeLog("def"); loggerFactory.finalize(); System.out.println("Check your files"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
勉強した個人的な意見・見解
* Singletonの応用で、ただMap(C#だとDictionary)を使って、複数オブジェクト持てるってだけじゃ?
参考文献
プログラム例としては一番分かり易いかもhttp://d.hatena.ne.jp/unageanu/20091215/1260882880
http://www.syboos.jp/sysdesign/doc/20080624145103439.html?page=1
http://www.itsenka.com/contents/development/designpattern/flyweight.html
http://telecastravinsky.blog.fc2.com/blog-entry-5.html
あんま関係ないけどサンプル書く時に読み返した記事