English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Androidのプログラミングデザインパターンの工場メソッドパターンの実例詳細解説

この記事では、Androidプログラミングデザインパターンの工場メソッドパターンについて説明します。以下に詳細を示します。

1. 介绍

工場メソッドパターン(Factory Pattern)は、作成型デザインパターンの1つです。工場メソッドパターンは構造が単純で、私たちの日常開発で非常に広く使用されています。あなたはまだ知らないかもしれませんが、あなたはこのパターンを何度も使っています。例えば、AndroidのActivityの各ライフサイクルメソッドでは、onCreateメソッドが工場メソッドとして見ることができます。そこで、Viewを構築し、setContentViewを通じてフレームワークに返すことができます。関連する内容は後で説明しますが、まず工場メソッドパターンの定義を見てみましょう。

2. 定義

オブジェクトの作成に使用するインターフェースを定義し、サブクラスがどのクラスをインスタンス化するかを決定させます。

3. 使用シーン

複雑なオブジェクトを生成する必要がある場所では、工場メソッドパターンを使用できます。複雑なオブジェクトは工場メソッドパターンに適していますが、newで生成するオブジェクトは工場メソッドパターンを使用する必要はありません。

4. シンプルな実装

抽象製品クラス:

public abstract class Product {
  /**
   * 製品クラスの抽象メソッド
   * 具体的製品クラスで実装します。
   * */
  public abstract void method();
}

具体的製品クラスA:

public class ConcreteProductA extends Product {
  @Override
  public void method() {
    System.out.println("私は具体的な製品A");
  }
}

具体的製品クラスB:

public class ConcreteProductB extends Product {
  @Override
  public void method() {
    System.out.println("私は具体的な製品B");
  }
}

抽象工場クラス:

public abstract class Factory {
  /**
   * 抽象工場メソッド
   * 具体的にはサブクラスで実現されます
   * 
   * @return 具体的製品オブジェクト
   * */
  public abstract Product createProduct();
}

具体的工場クラス:

public class ConcreteFactory extends Factory {
  /**
   * 具体的な工場クラス
   * */
  @Override
  public Product createProduct() {
    return new ConcreteProductA();
  }
}

クライアントクラス:

public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product product = factory.createProduct();
    product.method();
  }
}

結果:

私は具体的な製品A

ここに含まれる役割は非常にシンプルで、主に以下の4つのモジュールに分けられます。1つは抽象工場で、工場メソッドパターンの核心です;2つ目は具体的工場で、具体的なビジネスロジックを実現します;3つ目は抽象製品で、工場メソッドパターンが作成する製品の親クラスです;4つ目は具体的製品で、抽象製品の特定の製品を実現するオブジェクトです。

上記のコードでは、Clientクラスで工場オブジェクトを構築し、それを使用して製品オブジェクトを作成しました。ここで得た製品オブジェクトはConcreteProductAのインスタンスですが、ConcreteProductBのインスタンスを得たい場合は、ConcreteFactoryのロジックを変更するだけで良いです:

public class ConcreteFactory extends Factory {
  /**
   * 具体的な工場クラス
   * */
  @Override
  public Product createProduct() {
    //return new ConcreteProductA();
    return new ConcreteProductB();
  }
}

この方法は非常に一般的で、どの製品が必要かによってその製品を作成し、時には反射を使用してより簡潔に具体的な製品オブジェクトを作成することもできます。その場合、工場メソッドのパラメータリストにClassクラスを入力して、どの製品クラスであるかを決定する必要があります:

public abstract class Factory {
  /**
   * 抽象工場メソッド
   * 具体的にはサブクラスで実現されます
   * 
   * @param clz 製品オブジェクトのクラスタイプ
   * 
   * @return 具体的製品オブジェクト
   * */
  public abstract <T extends Product> T createProduct(Class<T> clz);
}

具体的工場クラスでは、クラスの例を反射を使用して取得するだけで済みます:

public class ConcreteFactory extends Factory {
  /**
   * 具体的な工場クラス
   * */
  @SuppressWarnings("unchecked")
  @Override
  public <T extends Product> T createProduct(Class<T> clz) {
    Product product = null;
    try {
      product = (Product) Class.forName(clz.getName()).newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)product;
  }
}

最後に、Clientの実装を見てみましょう:

public class Client {
  public static void main(String[] args) {
    Factory factory = new ConcreteFactory();
    Product product = factory.createProduct(ConcreteProductB.class);
    product.method();
  }
}

どのクラスのオブジェクトが必要な場合は、そのクラスのタイプを入力してください。この方法は簡潔で動的です。この方法が好きでない場合は、各製品ごとに具体的な工場を定義することもできます。各工場が役割を果たします。

public class ConcreteFactoryA extends Factory {
  /**
   * 具体的な工場クラス
   **/
  @Override
  public Product createProduct() {
    return new ConcreteProductA();
  }
}
public class ConcreteFactoryB extends Factory {
  /**
   * 具体的な工場クラス
   **/
  @Override
  public Product createProduct() {
    return new ConcreteProductB();
  }
}
public class Client {
  public static void main(String[] args) {
    Factory factoryA = new ConcreteFactoryA();
    Product productA = factoryA.createProduct();
    productA.method();
    Factory factoryB = new ConcreteFactoryB();
    Product productB = factoryB.createProduct();
    productB.method();
  }
}

このように複数の工場を持つ方法は、多工場方法パターンと呼ばれます。同様に、最初の工場方法パターンに戻ります。私たちの工場が1つしかない場合、私たちは工場に抽象クラスを提供しました。それでは、それを簡略化することができますか?あなたの工場クラスが1つしかないことを確信している場合、抽象クラスを簡略化することは問題ありません。私たちは対応する工場メソッドを静的メソッドに変更するだけでよいです:

public class Factory {
  /**
   * 具体的な工場クラス
   **/
  @Override
  public static Product createProduct() {
    return new ConcreteProductA();
  }
}

このような方法は、シンプルな工場パターンや静的工場パターンとも呼ばれ、工場メソッドパターンの弱化版です。

実際にはここまで来て、工場メソッドパターンがデザイン原則に完全に従っており、オブジェクト間の依存関係を低減していることがわかります。工場メソッドパターンは抽象のアーキテクチャに依存しており、インスタンス化のタスクをサブクラスに任せることができ、非常に拡張性があります。

第5章 Androidソースコード中的工場メソッドパターン

Activityのさまざまなライフサイクル

ArrayListとHashSet

第6章 まとめ

優点:

工場メソッドパターンはデザイン原則に完全に従っており、オブジェクト間の依存関係を低減しています。上位モジュールは、製品の抽象クラスのみを知る必要があり、他の実装については気にする必要はありません。

優れた封装性、明確なコード構造。拡張性が良い。

欠点:

工場メソッドパターンに新しい製品を追加するたびに、新しい製品クラスを書かなければなりません。同時に抽象レイヤーも導入する必要があり、これはクラス構造の複雑化につながるため、ある程度シンプルな場合には、工場メソッドパターンを使用するかどうかは、設計者が利点と欠点を検討する必要があります。

Androidに関するさらに詳細な内容に興味を持つ読者は、以下のサイトの特集を参照してください:《Android開発入門と進階ガイド》、《Androidデバッグ技術とよくある問題の解決方法集》、《Android基本コンポーネントの使い方総覧》、《AndroidビューViewの技術的な使い方総覧》、《Androidレイアウトlayoutの技術的な使い方総覧》および《Androidコントロールの使い方総覧》

この記事に記載されている内容が皆様のAndroidプログラム設計に役立つことを願っています。

声明:この記事の内容はインターネットから提供され、著作権者に帰属します。インターネットユーザーによって自発的に提供されたコンテンツであり、このサイトは所有権を持ちません。また、人工編集は行われておらず、関連する法的責任も負いません。著作権侵害の可能性のある内容が見つかった場合は、以下のメールアドレスにご連絡ください:notice#oldtoolbag.com(メールを送信する際には、#を@に変更してください)で報告し、関連する証拠を提供してください。一旦確認ができたら、このサイトは即座に侵害される可能性のあるコンテンツを削除します。

おすすめ