Java デザインパターン 〜シングルトン パターン〜

Androidアプリ作成の予備知識として、オブジェクト指向、クラスの組み合わせ方の王道としてデザインパターンに関して記載していきます。

作成したコードは、Gitにアップしてあります。

シングルトン

シングルトンパターンは、一個のオブジェクトを共有したい時に使用します。
つまり、プログラムが起動している最中では1つだけ存在するオブジェクト(クラス)になります。

例えば、共通で使用するデータを保持する役目をこのクラスに持たせようとした時に便利は実装方法です。
文言だけではイマイチ。。。なのでコードを交えて記載します。

シングルトンサンプル

実行結果は下のようになります。

Mainクラス
Singletonクラス

処理概要

シングルトンクラス(SingletonCls)を定義しておきます。

public class SingletonCls {
    /** このクラスのインスタンス */
    private static SingletonCls instance;
    /** 設定情報1 */
    private int setting1;
    /** 設定情報2 */
    private String setting2;

    public static SingletonCls getInstance() {
        if (instance == null) {
            instance = new SingletonCls();
        }
        return instance;
    }

    /** コンストラクタは外部から参照不可 */
    private SingletonCls() {
    }

    /**
     * @return the setting1
     */
    public int getSetting1() {
        return setting1;
    }

    /**
     * @param setting1 the setting1 to set
     */
    public void setSetting1(int setting1) {
        this.setting1 = setting1;
    }

    /**
     * @return the setting2
     */
    public String getSetting2() {
        return setting2;
    }

    /**
     * @param setting2 the setting2 to set
     */
    public void setSetting2(String setting2) {
        this.setting2 = setting2;
    }
}

このクラスをMainメソッドから呼び出して使用します。

public class SingletonMain {
    public static void main(String[] args) {
        SingletonMain main = new SingletonMain();
        // シングルトンクラスを取得する(メソッドのstatic呼び出し)
        SingletonCls single = SingletonCls.getInstance();
        single.setSetting1(12);
        single.setSetting2("設定情報2");

        // 設定情報を表示する
        main.showSetting();

        // 設定情報を変更する
        single.setSetting1(99);
        single.setSetting2("こんばんは");

        // 設定情報を表示する
        main.showSetting();
    }

    /** 設定情報を表示する */
    public void showSetting() {
        SingletonCls single = SingletonCls.getInstance();
        System.out.println("**** 設定情報 *****");
        System.out.println("設定情報1: " + single.getSetting1());
        System.out.println("設定情報2: " + single.getSetting2());
        System.out.println("*****************");
    }
}

シングルトンクラスは、getInstance()でしかインスタンスが取得できないように作っています。

public static SingletonCls getInstance() {
    if (instance == null) {
        instance = new SingletonCls();
    }
    return instance;
}

/** コンストラクタは外部から参照不可 */
private SingletonCls() {
}

まとめ

上のように、シングルトンクラスはインスタンスが1つなので、常に保持している値が(各フィールドごとに)1つになります。なので、処理をしている最中に「設定情報」などを変更して何かしらの処理を行う時には便利は実装方法です。
他にも、アイディア次第でいろんなことができます。

余談

これがシングルトンでない場合は。。。
インスタンスが別々になるので、上のコードshowSetting()に引数を与えるとか他の方法をとる必要があります。

/** 設定情報を表示する */
public void showSetting() {
    // この部分を変更する必要がある
    SingletonCls single = SingletonCls.getInstance();
    System.out.println("**** 設定情報 *****");
    System.out.println("設定情報1: " + single.getSetting1());
    System.out.println("設定情報2: " + single.getSetting2());
    System.out.println("*****************");
}

シングルトンの場合は、getInstance()で(static呼び出しなので)いつでも設定情報を持っているインスタンスを取得できますが、これをシングルトンではない実装にするときは下のようになります。

実装は下のようになりました。

//// シングルトンではないパターン ////
NoSingletonCls noSingle = main.new NoSingletonCls();
// インナークラスなので参照可能、普通はこんな実装をしない
noSingle.setting1 = 1;
noSingle.setSetting2("内部設定");
main.showInnerSetting(noSingle);
// 値を変更する
noSingle.setSetting1(33);
noSingle.setSetting2("内部情報123");
main.showInnerSetting(noSingle);

とりあえずは、インスタンスを毎回作成する必要があるので、この部分が無駄になるわけです。
シングルトンは1つなので余計なPCリソース(メモリなど)を使用しなくて良いので、経済的な実装方法です(笑)

でわでわ。。。



Java デザインパターン 〜Abstract Factory パターン〜

Androidアプリ作成の予備知識として、オブジェクト指向、クラスの組み合わせ方の王道としてデザインパターンに関して記載していきます。
作成したコードはgitにアップしてあります。
ちなみにEclipseで実装しました。

Abstract Factoryパターン

決められた一部の処理をごっそりと入れ替えることができる、デザインパターンです。

具体的に。。。

親クラスで、一通りの処理を実装しておき、変更、もしくはいろんなパターンで実装したい時に、この方法が使えます。
例として、JavaFXでは、Applicationクラスのstart()メソッドをオーバーライドするという形で実装されています。これは初めてプログラムを作成する人向けに記載しました、とりあえずは写経して動かしてみるのがいちばんだと思いますのでコードと動かすための予備知識的なことを記載しました。

実装サンプル

設計

ハローワールドのプログラムを作成します。ただし、表示する文言は実行するクラスによって変更できるように実装します。

実装

親クラス

gitのソースMain

public abstract class Main {

    public void hello() {
        String value = getValue();
        System.out.println(value);
    }
    //// 抽象メソッド ////
    protected abstract String getValue();
}

上の抽象メソッドは処理の中身がありません。これはこの「抽象クラス」を継承する子クラスで実装します。

子クラス

gitのソースChildA

public class ChildA extends Main {
    public static void main(String[] args) {
        ChildA main = new ChildA();
        main.hello();
    }

    @Override
    public String getValue() {
        return "Hello World";
    }
}

実行結果

こんな感じで、実行できます。

文言の変更

ここで、思うのは「ハローワールドはもういいかな?」というところだと思います。
なので、変更しようと思いますが。。。
この実装はこのまま残しておきます。
しかし、変更はしたいので。。。どーするか?

子クラスをもう1つ

gitのソースChildB

public class ChildB extends Main {
    public static void main(String[] args) {
        ChildB main = new ChildB();
        main.hello();
    }

    public String getValue() {
        return "Let's Java!";
    }
}

実装する内容はほとんど変わりませんが、ちょっと違います。
実行結果は以下の通り

こんな感じです。

でわでわ。。。