第20章 Flyweight ~同じものを共有して無駄をなくす~

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

プログラミング第5回 1 while ループ 文字列の操作
プログラミング実習 1 ・ 2 ク ラス 第 2 週目 担当教員 : 渡邊 直樹. 課題 2 ● 2 × 2型行列の固有値, 固有ベクトルを求め る EigMatrix.java というプログラムを作成せ よ。 ● 行列の各要素はコマンド・プロンプトから入力 ● 計算した結果もコマンド・プロンプトに表示.
情報処理演習C2 ファイル操作について (2).
IO - 入出力 小西 亨.
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング基礎I(再) 山元進.
プログラミング基礎I(再) 山元進.
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
独習Java ・ 10.6  Hashtableクラス ・ 10.7  String Tokenizerクラス  12月12日    小笠原 一恵.
String - 文字列 2009年10月9日 7ADD2116 佐藤洋輔.
第8回 プログラミングⅡ 第8回
プログラミング実習 1・2 クラス 第 1 週目 担当教員:  渡邊 直樹.
アルゴリズムとデータ構造 2011年6月13日
インタフェース プログラミング 第14回 インタフェース プログラミング第14回.
Bridge Pattern
オブジェクト指向入門.
アルゴリズムとデータ構造 2011年6月20日
情報処理技法 (Javaプログラミング)2 第2回 前期の復習(2)
第13回 ハッシュテーブルを使ったプログラム ~高速に検索するには?~.
~手続き指向からオブジェクト指向へ[Ⅱ]~
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
8.1 例外処理 8.2 catchブロックの検索 8.3 throwステートメント 8.4 例外とエラークラス 8.6 独自の例外
プログラミング言語入門 手続き型言語としてのJava
JAVA入門後期⑩ 情報処理試験例題解説.
UDPマルチキャストチャット                    空川幸司.
第9章 例外処理,パッケージ 9.1 例外処理 9.2 ガーベッジコレクション.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
リファレンスの復習と例外処理 2005年6月14日 海谷 治彦.
暗号技術 ~JAVAプログラム③~ (7週目)
第3回 2007年4月27日 応用Java (Java/XML).
コンパイラの解析 (3) クラスとインスタンスの初期化.
第6回 2007年6月1日 応用Java (Java/XML).
暗号技術 ~JAVAプログラム①~ (5週目)
オブジェクト指向 プログラミング 第七回 知能情報学部 新田直也.
10-1 SAXの概要 10-2 Saxプログラミングの基礎 10-3 saxのプログラム例
5.9 メソッドのオーバーロード 5.10 変数の引渡し 2003/11/21 紺野憲一
7.4 intanceof 演算子 7.5~7.9パッケージ 2003/11/28 紺野憲一
ソフトウェア制作論 平成30年11月21日.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
計算機プログラミングI 第5回 配列 文字列(Stringクラス) mainの引数 配列の利用例
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
15.1 文字列処理の基本 15.2 文字列処理用ライブラリ関数
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向 プログラミング 第九回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第八回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
C#プログラミング実習 第3回.
計算機プログラミングI 第3回 プリミティブ値 クラスメソッド クラス変数 式と演算 変数の利用
アルゴリズムとデータ構造 2012年6月11日
アルゴリズムとプログラミング (Algorithms and Programming)
暗号技術 ~JAVAプログラム②~ (6週目)
ソフトウェア制作論 平成30年11月14日.
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向 プログラミング 第四回 知能情報学部 新田直也.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
アルゴリズムとデータ構造 2012年6月21日
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
第6章 インターネットアプリケーション 6.1 インターネットアプリケーション 6.2 Javaによるネットワーク処理 6.3 電子メール
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
計算機プログラミングI 第5回 2002年11月7日(木) 配列: 沢山のデータをまとめたデータ どんなものか どうやって使うのか
Presentation transcript:

第20章 Flyweight ~同じものを共有して無駄をなくす~ 深澤研究室 M0 1w120399-6 西田 和馬

Flyweightパターンとは Flyweight とは、英語で「フライ級」 ボクシングで最も軽い階級 ⇨ オブジェクト(メモリの使用量)を「軽く」するもの Flyweightは、「インスタンスをできるだけ共有させて、無駄にnewしない」 インスタンスの生成「new」は、メモリを確保 多くの「new」はメモリの使用量の増加

サンプルプログラム コマンドラインで入力された値・文字を大きな文字で出力 大きな文字を構成するデータはtxtファイルで用意 数字は「0~9」 文字は ” - ” のみ 目的のファイルがない場合(” - ”以外の文字) 文字の後に ” ? ”をつけたものをフォントデータとして出力

「大きな文字」のtxtファイル big0.txt big1.txt big-.txt big9.txt

サンプルプログラムのクラス図

BigCharクラス ファイルから大きな文字のテキスト読み込み lineにファイル内容を一行書き、これをbufに追加 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に追加 StringBufferクラスではStringクラスと異なり一度オブジェクトの値を代入した後でもその値の変更が可能です。但し、値が不変な Stringクラスと比較すると値が同一の場合でもメモリ内に格納されている値の共有ができないなどあまり効率がよくありません。また初期容量を指定せず StringBufferオブジェクトを生成した場合は値の変更を見越して代入された値に16文字を加えた値がメモリ領域に確保されてしまいます。そのため値の変更がないのであればStringBufferクラスを使用すべきではありません。 fontdataに作成した文字列(テキスト内容)を格納 大きな文字はメモリ消費量が多い ⇨ BigCharのインスタンス共有を目指す

BigCharのインスタンスを共有しながら生成するクラス BigCharFactoryクラス 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); // BigCharのインスタンスを生成 pool.put("" + charname, bc); return bc; 文字列→インスタンスの対応関係を管理 ・ Singletonパターン - BigCharFactoryのインスタンスは1つで良い ・pool:これまでに作ったインスタンスを格納 ・pool内から目的の文字のインスタンスを検索しbcに格納 ⇨ ない場合は、bc = null

BigCharのインスタンスを共有しながら生成するクラス BigCharFactoryクラス 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); // BigCharのインスタンスを生成 pool.put("" + charname, bc); return bc; ・poolに目的の文字のインスタンスがない場合 引数charnameで与えられた文字に対応するBigCharのインスタンスを作成 poolに作成したインスタンスを登録

BigCharFactoryクラス 既に同じ文字のインスタンスを作っている場合 新しいインスタンスを作らない 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; 既に同じ文字のインスタンスを作っている場合 新しいインスタンスを作らない

BigStringクラス BigCharのインスタンスを保持 コマンドラインで指定した文字 文字列stringのi番目の文字を返す 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() { bigchars[i].print(); BigCharのインスタンスを保持 コマンドラインで指定した文字 文字列stringのi番目の文字を返す (先頭は0文字目) 文字列からn番目の文字列を抜き出すには、charAtメソッドを利用します。文字列の先頭は0文字目と見なします(よって、最後の文字は「length() -1」番目です)。 i番目の文字に対応するインスタンスを生成

Mainクラス 実行例 java Main 1212123 動作テスト用のクラス 出力 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(); 出力 実行例 java Main 1212123

プログラムの流れ 1212123 BigStringクラス 入力例 Mainクラス 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() { 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"); System.exit(0); } BigString bs = new BigString(args[0]); bs.print();

プログラムの流れ 1212123 1 1 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のインスタンスを生成 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() { bigchars[i].print(); 1212123 1 1

プログラムの流れ 1 1 BigCharクラス BigCharFactoryクラス import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; 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); 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 1

プログラムの流れ pool 1 BigCharクラス BigCharFactoryクラス import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; 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); 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; pool 1

プログラムの流れ pool 1 BigCharFactoryクラス 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

プログラムの流れ pool 1212123 2 2 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のインスタンスを生成 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() { bigchars[i].print(); 1212123 2 2

プログラムの流れ pool 1212123 1 1 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のインスタンスを生成 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() { bigchars[i].print(); 1212123 1 1

“12123”に対応するBigStringの インスタンスの様子

まとめ Flyweightは、「インスタンスを共有」 短所 newの削減 ⇨ メモリの消費量を削減 ⇨ プログラムの実行速度の向上 共有するインスタンスの変更は、複数箇所に影響 ⇨ 共有させるべきインスタンスとそうでないものを区別することが重要