...

第20章 Flyweight Flyweightパターンとは サンプルプログラム 「大きな

by user

on
Category: Documents
13

views

Report

Comments

Transcript

第20章 Flyweight Flyweightパターンとは サンプルプログラム 「大きな
2015/6/28
Flyweightパターンとは
• Flyweight とは、英語で「フライ級」
– ボクシングで最も軽い階級
⇨ オブジェクト(メモリの使用量)を「軽く」するもの
第20章 Flyweight
~同じものを共有して無駄をなくす~
• Flyweightは、「インスタンスをできるだけ共有
させて、無駄にnewしない」
深澤研究室 M0
1w120399-6
西田 和馬
– インスタンスの生成「new」は、メモリを確保
– 多くの「new」はメモリの使用量の増加
1
サンプルプログラム
2
「大きな文字」のtxtファイル
big0.txt
• コマンドラインで入力された値・文字を大きな文字で出力
big1.txt
– 大きな文字を構成するデータはtxtファイルで用意
• 数字は「0~9」
• 文字は ” - ” のみ
同様に、
big2.txt~
big8.txtも用意
– 目的のファイルがない場合(” - ”以外の文字)
• 文字の後に ” ? ”をつけたものをフォントデータとして出力
big-.txt
big9.txt
3
サンプルプログラムのクラス図
4
BigCharクラス
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
大きな文字を表現するクラス
public class BigChar {
private char charname;
// 文字の名前
private String fontdata;
// 大きな文字を表現する文字列('#' '.' '¥n'の列)
public BigChar(char charname) { // コンストラクタ
this.charname = charname;
try {
BufferedReader reader = new BufferedReader(
new FileReader("big" + charname + ".txt")
);
String line;
StringBuffer buf = new StringBuffer();
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append("¥n");
}
reader.close();
this.fontdata = buf.toString();
} catch (IOException e) {
this.fontdata = charname + "?";
}
}
public void print() { // 大きな文字を表示する
System.out.print(fontdata);
}
}
ファイルから大きな文字のテキスト読み込み
lineにファイル内容を一行書き、これをbufに追加
fontdataに作成した文字列(テキスト内容)を格納
大きな文字はメモリ消費量が多い
⇨ BigCharのインスタンス共有を目指す
5
6
1
2015/6/28
BigCharFactoryクラス
BigCharFactoryクラス
BigCharのインスタンスを共有しながら生成するクラス
BigCharのインスタンスを共有しながら生成するクラス
import java.util.HashMap;
import java.util.HashMap;
public class BigCharFactory {
// すでに作ったBigCharのインスタンスを管理
private HashMap pool = new HashMap();
// Singletonパターン
private static BigCharFactory singleton = new BigCharFactory();
// コンストラクタ
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
bc = new BigChar(charname);
// BigCharのインスタンスを生成
pool.put("" + charname, bc);
}
return bc;
}
}
public class BigCharFactory {
// すでに作ったBigCharのインスタンスを管理
private HashMap pool = new HashMap();
// Singletonパターン
private static BigCharFactory singleton = new BigCharFactory();
// コンストラクタ
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
bc = new BigChar(charname);
// BigCharのインスタンスを生成
pool.put("" + charname, bc);
}
return bc;
}
}
文字列→インスタンスの対応関係を管理
・poolに目的の文字のインスタンスがない場合
引数charnameで与えられた文字に対応する
BigCharのインスタンスを作成
・ Singletonパターン
- BigCharFactoryのインスタンスは1つで良い
・pool:これまでに作ったインスタンスを格納
・pool内から目的の文字のインスタンスを検索しbcに格納
⇨ ない場合は、bc = null
7
poolに作成したインスタンスを登録
BigCharFactoryクラス
BigStringクラス
BigCharのインスタンスを共有しながら生成するクラス
BigCharを集めて作った「大きな文字列」を表すクラス
import java.util.HashMap;
public class BigCharFactory {
// すでに作ったBigCharのインスタンスを管理
private HashMap pool = new HashMap();
// Singletonパターン
private static BigCharFactory singleton = new BigCharFactory();
// コンストラクタ
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
bc = new BigChar(charname);
pool.put("" + charname, bc);
既に同じ文字のインスタンスを作っている場合
// BigCharのインスタンスを生成
}
return bc;
新しいインスタンス
を作らない
}
8
public class BigString {
// 「大きな文字」の配列
private BigChar[] bigchars;
BigCharのインスタンスを保持
// コンストラクタ
public BigString(String string) {
bigchars = new BigChar[string.length()];
コマンドラインで指定した文字
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigchars.length; i++) {
bigchars[i] = factory.getBigChar(string.charAt(i));
}
文字列stringのi番目の文字を返す
}
(先頭は0文字目)
// 表示
public void print() {
for (int i = 0; i < bigchars.length; i++) {
i番目の文字に対応するインスタンスを生成
bigchars[i].print();
}
}
}
9
}
10
プログラムの流れ
Mainクラス
動作テスト用のクラス
public class Main {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Usage: java Main digits");
System.out.println("Example: java Main 1212123");
System.exit(0);
}
BigString bs = new BigString(args[0]);
bs.print();
}
}
入力例
BigStringクラス
public class BigString {
// 「大きな文字」の配列
private BigChar[] bigchars;
// コンストラクタ
public BigString(String string) {
bigchars = new BigChar[string.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigchars.length; i++) {
bigchars[i] = factory.getBigChar(string.charAt(i));
}
}
// 表示
public void print() {
for (int i = 0; i < bigchars.length; i++) {
bigchars[i].print();
}
}
}
1212123
出力
Mainクラス
public class Main {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Usage: java Main digits");
System.out.println("Example: java Main 1212123");
実行例
java Main 1212123
System.exit(0);
}
BigString bs = new BigString(args[0]);
bs.print();
}
}
11
12
2
2015/6/28
プログラムの流れ
BigCharFactoryクラス
import java.util.HashMap;
1
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
// BigCharのインスタンスを生成
bc = new BigChar(charname);
pool.put("" + charname, bc);
BigCharクラス
BigCharFactoryクラス
public class BigString {
// 「大きな文字」の配列
private BigChar[] bigchars;
// コンストラクタ
public BigString(String string) {
bigchars = new BigChar[string.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigchars.length; i++) {
bigchars[i] = factory.getBigChar(string.charAt(i));
}
}
// 表示
public void print() {
for (int i = 0; i < bigchars.length; i++) {
bigchars[i].print();
}
}
}
1212123
public class BigCharFactory {
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new
BigCharFactory();
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
プログラムの流れ
BigStringクラス
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new
BigCharFactory();
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
1
1
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
1
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
// BigCharのインスタンスを生成
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
}
return bc;
}
}
}
}
public class BigChar {
private char charname;
// 文字の名前
private String fontdata;
public BigChar(char charname) { // コンストラクタ
this.charname = charname;
try {
BufferedReader reader = new BufferedReader(
new FileReader("big" + charname + ".txt")
);
String line;
StringBuffer buf = new StringBuffer();
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append("¥n");
}
reader.close();
this.fontdata = buf.toString();
} catch (IOException e) {
this.fontdata = charname + "?";
}
}
public void print() {
// 大きな文字を表示する
System.out.print(fontdata);
}
}
13
プログラムの流れ
14
プログラムの流れ
BigCharクラス
BigCharFactoryクラス
BigCharFactoryクラス
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new
BigCharFactory();
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
// BigCharのインスタンスを生成
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
}
}
1
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new
BigCharFactory();
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
// BigCharのインスタンスを生成
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
}
}
public class BigChar {
private char charname;
// 文字の名前
private String fontdata;
public BigChar(char charname) { // コンストラクタ
this.charname = charname;
try {
BufferedReader reader = new BufferedReader(
new FileReader("big" + charname + ".txt")
);
String line;
StringBuffer buf = new StringBuffer();
while ((line = reader.readLine()) != null) {
buf.append(line);
buf.append("¥n");
}
reader.close();
this.fontdata = buf.toString();
} catch (IOException e) {
this.fontdata = charname + "?";
}
}
public void print() {
// 大きな文字を表示する
System.out.print(fontdata);
}
}
1
15
プログラムの流れ
BigCharFactoryクラス
プログラムの流れ
BigStringクラス
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new
BigCharFactory();
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
// BigCharのインスタンスを生成
2
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
16
BigCharFactoryクラス
public class BigString {
// 「大きな文字」の配列
private BigChar[] bigchars;
// コンストラクタ
public BigString(String string) {
bigchars = new BigChar[string.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigchars.length; i++) {
bigchars[i] = factory.getBigChar(string.charAt(i));
}
}
// 表示
public void print() {
for (int i = 0; i < bigchars.length; i++) {
bigchars[i].print();
}
}
}
1212123
2
BigStringクラス
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool = new HashMap();
private static BigCharFactory singleton = new
BigCharFactory();
private BigCharFactory() {
}
// 唯一のインスタンスを得る
public static BigCharFactory getInstance() {
return singleton;
}
// BigCharのインスタンス生成(共有)
public synchronized BigChar getBigChar(char charname) {
BigChar bc = (BigChar)pool.get("" + charname);
if (bc == null) {
// BigCharのインスタンスを生成
1
bc = new BigChar(charname);
pool.put("" + charname, bc);
}
return bc;
}
public class BigString {
// 「大きな文字」の配列
private BigChar[] bigchars;
// コンストラクタ
public BigString(String string) {
bigchars = new BigChar[string.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for (int i = 0; i < bigchars.length; i++) {
bigchars[i] = factory.getBigChar(string.charAt(i));
}
}
// 表示
public void print() {
for (int i = 0; i < bigchars.length; i++) {
bigchars[i].print();
}
}
}
1212123
1
}
}
}
17
18
3
2015/6/28
“12123”に対応するBigStringの
インスタンスの様子
まとめ
• Flyweightは、「インスタンスを共有」
– newの削減
⇨ メモリの消費量を削減
⇨ プログラムの実行速度の向上
• 短所
– 共有するインスタンスの変更は、複数箇所に影響
⇨ 共有させるべきインスタンスとそうでないものを区別することが重要
19
20
4
Fly UP