1前書き

ソフトウェア工学では、設計パターンはソフトウェア設計で最も一般的に遭遇する問題に対する確立された解決策を記述します。

これは、経験豊富なソフトウェア開発者による試行錯誤を通じて、長期にわたって進化したベストプラクティスを表しています。

デザインパターンは本https://books.google.co.in/books?id=K4qv1D-LKhoCの後に人気を博しました

この記事では、創造的デザインパターンとそのタイプについて探ります。また、いくつかのコードサンプルを見て、これらのパターンが私たちの設計に適合する状況について説明します。


2創造的デザインパターン

  • Creational Design Patternsは、オブジェクトがどのように作成されるのかに関係しています。


new

演算子は、アプリケーション全体にオブジェクトを分散させるため、しばしば有害と見なされます。時間が経つにつれて、クラスが密接に結合されるようになるため、実装を変更することは困難になる可能性があります。

Creational Design Patternsは、クライアントを実際の初期化プロセスから完全に切り離すことによってこの問題に対処します。

この記事では、4種類の創造的デザインパターンについて説明します。

  1. シングルトン – オブジェクトの最大1つのインスタンスのみが存在することを保証

アプリケーション全体
。 Factoryメソッド – いくつかの関連クラスのオブジェクトを作成せずに作成する

作成する正確なオブジェクトを指定する
。抽象ファクトリ – 関連する依存オブジェクトのファミリーを作成します

  1. Builder



    ステップバイステップのアプローチを使用して複雑なオブジェクトを構築する

それでは、これらの各パターンについて詳しく説明しましょう。


3シングルトンデザインパターン

シングルトンデザインパターンは、Java仮想マシン全体にオブジェクトのインスタンスが1つだけ存在するようにすることによって、特定のクラスのオブジェクトの初期化をチェックすることを目的としています。

また、シングルトンクラスは、オブジェクトへの一意のグローバルアクセスポイントを1つ提供するので、その後のアクセスポイントへの呼び出しごとにその特定のオブジェクトのみが返されます。


3.1. シングルトンパターンの例

シングルトンパターンはGoFによって導入されましたが、オリジナルの実装はマルチスレッドシナリオでは問題があることが知られています。

そこで、ここでは、静的な内部クラスを利用する、より最適なアプローチに従います。

public class Singleton  {
    private Singleton() {}

    private static class SingletonHolder {
        public static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

ここでは、

Singleton

クラスのインスタンスを保持する

static

内部クラスを作成しました。インスタンスが

getInstance()

メソッドを呼び出したときにのみインスタンスを作成し、外部クラスがロードされたときには作成しません。

これは同期を必要とせず、スレッドセーフであり、遅延初期化を強制し、そして比較的定型的ではないので、これはシングルトンクラスのために広く使われているアプローチです。

また、コンストラクターには

private

access修飾子があります。

public

コンストラクタは誰でもそれにアクセスして新しいインスタンスの作成を開始できることを意味するため、これはSingletonを作成するための要件です。

覚えておいて、これは元のGoFの実装ではありません。オリジナルバージョンについては、JavaのSingletonsのリンク:/java-singleton[このリンクされたBaeldungの記事]をご覧ください。


3.2. シングルトンデザインパターンを使用する場合

  • 作成にコストがかかるリソース(データベース接続など)

オブジェクト)
** すべてのロガーをシングルトンとして保持することを推奨

パフォーマンス
** 構成設定へのアクセスを提供するクラス

応用
** 共有モードでアクセスされるリソースを含むクラス


4ファクトリーメソッドデザインパターン

ファクトリデザインパターンまたはファクトリメソッドデザインパターンは、Javaで最もよく使用されるデザインパターンの1つです。

GoFによると、このパターンは「オブジェクトを作成するためのインタフェースを定義しますが、どのクラスをインスタンス化するかをサブクラスに決定させます。** Factoryメソッドでは、クラスはサブクラスへのインスタンス化を延期します」

このパターンは、一種の仮想コンストラクタを作成することによって、クライアントから特定のファクトリクラスにクラスを初期化する責任を委任します。

これを達成するために、私たちはオブジェクトを私たちに提供するファクトリに頼り、実際の実装の詳細を隠します。作成されたオブジェクトは、共通のインタフェースを使ってアクセスされます。


4.1. ファクトリーメソッド設計パターン例

この例では、いくつかの具象クラスによって実装される

Polygon

インターフェースを作成します。

PolygonFactory

は、このファミリからオブジェクトを取得するために使用されます。

リンク:/uploads/Factory

Method

Design__Pattern.png%201280w[]

最初に

Polygon

インターフェースを作成しましょう。

public interface Polygon {
    String getType();
}

次に、

Square



Triangle、

などの実装をいくつか作成します。

このインタフェースを実装し、

Polygon

タイプのオブジェクトを返します。

これで、辺の数を引数として取り、このインタフェースの適切な実装を返すファクトリを作成できます。

public class PolygonFactory {
    public Polygon getPolygon(int numberOfSides) {
        if(numberOfSides == 3) {
            return new Triangle();
        }
        if(numberOfSides == 4) {
            return new Square();
        }
        if(numberOfSides == 5) {
            return new Pentagon();
        }
        if(numberOfSides == 7) {
            return new Heptagon();
        }
        else if(numberOfSides == 8) {
            return new Octagon();
        }
        return null;
    }
}

オブジェクトを直接初期化しなくても、クライアントがこのファクトリに依存して適切な

Polygon

を提供できることに注目してください。


4.2. ファクトリーメソッドデザインパターンを使用する場合

  • インタフェースや抽象クラスの実装が

頻繁に変わると予想される
** 現在の実装が新しいものに快適に対応できない場合

変化する
** 初期化プロセスが比較的簡単で、

コンストラクタはほんの一握りのパラメータを必要とします


5抽象的なファクトリーデザインパターン

前のセクションでは、ファクトリメソッドデザインパターンを使用して単一ファミリに関連するオブジェクトを作成する方法を説明しました。

対照的に、抽象ファクトリーデザインパターンは、関連または従属オブジェクトのファミリーを作成するために使用されます。工場の工場と呼ばれることもあります。

詳しい説明は、http://www.baeldung.com/java-abstract-factory-pattern[Abbstract Factory]チュートリアルをご覧ください。


6. ビルダーデザインパターン

ビルダーデザインパターンは、比較的複雑なオブジェクトの作成に対処するように設計されたもう1つの作成パターンです。

オブジェクトを作成する複雑さが増すと、Builderパターンは別のオブジェクト(ビルダー)を使用してオブジェクトを構成することによってインスタンス化プロセスを分離することができます。

このビルダーを使用して、簡単なステップバイステップのアプローチを使用して他の多くの同様の表現を作成できます。


6.1. ビルダーパターンの例

GoFによって導入されたオリジナルのBuilderデザインパターンは抽象化に焦点を当てており、複雑なオブジェクトを扱う場合には非常に優れていますが、デザインは少し複雑です。

Joshua Blochは、彼の著書Effective Javaの中で、(https://en.wikipedia.org/wiki/Fluent__interface[fluent design]を使用しているため)きれいで読みやすいビルダーパターンの改良版を紹介しました。クライアントの観点から使用してください。この例では、そのバージョンについて説明します。

この例には、

Static

内部クラスとしてビルダーを含む

BankAccount

クラスが1つだけあります。

public class BankAccount {

    private String name;
    private String accountNumber;
    private String email;
    private boolean newsletter;

   //constructors/getters

    public static class BankAccountBuilder {
       //builder code
    }
}

外部オブジェクトから直接アクセスしたくないため、フィールドのすべてのアクセス修飾子は

private

として宣言されています。

このクラスに割り当てられたBuilderだけがそれにアクセスできるように、コンストラクタも

private

です。コンストラクターに設定されているすべてのプロパティーは、引数として指定したBuilderオブジェクトから抽出されます。


BankAccountBuilder



static

内部クラスに定義しました。

public static class BankAccountBuilder {

    private String name;
    private String accountNumber;
    private String email;
    private boolean newsletter;

    public BankAccountBuilder(String name, String accountNumber) {
        this.name = name;
        this.accountNumber = accountNumber;
    }

    public BankAccountBuilder withEmail(String email) {
        this.email = email;
        return this;
    }

    public BankAccountBuilder wantNewsletter(boolean newsletter) {
        this.newsletter = newsletter;
        return this;
    }

    public BankAccount build() {
        return new BankAccount(this);
    }
}

外側のクラスに含まれるのと同じフィールドのセットを宣言したことに注意してください。必須フィールドはすべて内部クラスのコンストラクタへの引数として必須ですが、残りのオプションフィールドはsetterメソッドを使用して指定できます。

この実装は、setterメソッドにBuilderオブジェクトを返させることで、流暢なデザイン手法もサポートします。

最後に、buildメソッドは外部クラスのプライベートコンストラクタを呼び出し、それ自体を引数として渡します。返された

BankAccount

は、

BankAccountBuilder

で設定されたパラメータでインスタンス化されます。

実際のビルダーパターンの簡単な例を見てみましょう。

BankAccount newAccount = new BankAccount
  .BankAccountBuilder("Jon", "22738022275")
  .withEmail("[email protected]")
  .wantNewsletter(true)
  .build();


6.2. Builderパターンを使用する場合

  1. オブジェクトの作成に関わるプロセスが非常に複雑な場合、

必須およびオプションのパラメータが多数あります
。コンストラクタパラメータの数が増えると、

コンストラクタの大規模なリスト
。クライアントがオブジェクトに対して異なる表現を期待している場合

構築された


7. 結論

この記事では、Javaの創造的デザイン・パターンについて学びました。また、シングルトン、ファクトリメソッド、抽象ファクトリ、ビルダーパターンの4つの異なるタイプ、それらの利点、例、およびそれらをいつ使用すべきかについても説明しました。

いつものように、完全なコードスニペットはhttps://github.com/eugenp/tutorials/tree/master/patterns/design-patterns[GitHubで入手可能]です。