Help us understand the problem. What is going on with this article?

デザインパターン ~Flyweight~

More than 1 year has passed since last update.

1. はじめに

GoFのデザインパターンにおける、Flyweightパターンについてまとめます。

2. Flyweightパターンとは

  • Flyweightという英単語は、フライ級という意味になります。ボクシングで最も体重が軽い階級を表します。
  • Flyweightパターンにおいての重さとは、メモリ使用量のことになります。
  • Flyweightパターンは、インスタンスをできるだけ共有させて、メモリ使用量を軽くする方式です。
  • GoFのデザインパターンでは、構造に関するデザインパターンに分類されます。

3. サンプルクラス図

Flyweight.PNG

4. サンプルプログラム

ファイルから大きな文字のテキストを読み込んで、それを表示するプログラムです。

4-1. BigCharクラス

大きな文字を表すクラスです。

BigChar.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BigChar {

    // 文字の名前
    private char charname;
    // 大きな文字を表現する文字列('#' '.' '\n'の列)
    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);
    }
}

4-2. BigCharFactoryクラス

BigCharのインスタンスを共有しながら生成するクラスです。

BigCharFactory.java
import java.util.HashMap;

public class BigCharFactory {

    // すでに作ったBigCharのインスタンスを管理
    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) {
            bc = new BigChar(charname);
            pool.put("" + charname, bc);
        }
        return bc;
    }
}

4-3. BigStringクラス

BigCharを集めて作った「大きな文字列」を表すクラスです。

BigString.java
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();
        }
    }
}

4-4. Mainクラス

メイン処理を行うクラスです。

Main.java
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();
    }
}

4-5. データ

以下のtxtファイルをご参照ください。
https://github.com/i-tanaka730/design_pattern/tree/master/src/Flyweight

4-6. 実行結果

..##########....
..##......##....
..........##....
........##......
......##........
......##........
......##........
................
......##........
..######........
......##........
......##........
......##........
......##........
..##########....
................
..##########....
..##......##....
..........##....
........##......
......##........
......##........
......##........
................
..##########....
..##............
..##............
..########......
..........##....
..##......##....
....######......
................。

5. メリット

インスタンスを共有すると、毎回newする必要がなく、メモリ使用量が少なくなります。より一般的に言えば、インスタンスを共有すると、インスタンスを生成するのに必要なリソースの量を減らすことができます。リソースとはコンピュータ上の資源であり、メモリはリソースの一種です。
時間もリソースの一種になります。インスタンスをnewするとき、一定の時間がかかるとすると、Flyweightパターンを使ってインスタンスを共有すれば、インスタンスをnewする数を減らすことができます。これによってプログラムのスピードを上げることができます。

6. GitHub

7. デザインパターン一覧

8. 参考

今回の記事、及びサンプルプログラムは、以下の書籍を元に作成させて頂きました。

大変分かりやすく、勉強になりました。感謝申し上げます。
デザインパターンやサンプルプログラムについての説明が詳細に書かれていますので、是非書籍の方もご覧ください。

i-tanaka730
福井でWeb・スマホ・Windowsのアプリケーション開発をしてます🍀 ストレスの軽減、勉強・仕事の効率化、人間関係についても勉強中です🌈 【C# / Java / PHP / Python / JS / Flutter / .NET / Docker / UML etc.】
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした