目次
Javaちょっとできるプログラマ。教育業界のエンジニアです。
複数の製品インスタンス (ConcreteProduct1,2,3,...) を用いた複雑な手順で何らかのアウトプット1を出す場合を考えます。他にも同様の手順でアウトプット2,3,4,...を出すことを求められている場合、抽象化した工場 (AbstractFactory) を用意しておき、抽象工場AbstractFactoryから抽象製品群 (AbstractProduct1,2,3,...) を生成できるようにし、「抽象製品群AbstractProduct1,2,3,...を用いてアウトプットnを出す複雑な手順」の共通化できる一部をテンプレートとして用意しておくと便利です。
各アウトプット1,2,3,...毎の差異となる具体的な部分は、抽象工場AbstractFactoryを継承した具体的な工場 (ConcreteFactory) および抽象製品AbstractProduct1,2,3,...を継承した具体的な製品群 (ConcreteProduct1,2,3,...) で実装します。
サンプルコード
フォルダ構成
$ tree .
.
|-- concrete1
| |-- ConcreteFactory.java
| |-- ConcreteProduct1.java
| |-- ConcreteProduct2.java
| `-- ConcreteProduct3.java
|-- factory
| |-- AbstractFactory.java
| |-- AbstractProduct1.java
| |-- AbstractProduct2.java
| |-- AbstractProduct3.java
| `-- AbstractSuper.java
`-- sample.java
Main
抽象工場から抽象製品を生成し、抽象製品を用いた (複雑な) 手順でアウトプットを出します。
sample.java
import factory.AbstractFactory;
import factory.AbstractSuper;
import factory.AbstractProduct1;
import factory.AbstractProduct2;
import factory.AbstractProduct3; //具体的な工場および製品は利用しないためimportは不要
class Sample {
public static void main(String args[]) {
// 抽象的な工場を用意
// - アウトプットnの形式 (concrete_i: n進数を扱う) はここで選択
// - ここではconcrete1という、16進数を扱う工場を選択
AbstractFactory factory = AbstractFactory.getFactory("concrete1.ConcreteFactory");
// 抽象的な工場から複数の抽象的な製品を生成
AbstractSuper product1 = factory.createProduct1('F'); //1桁目の数値を表現する製品
AbstractSuper product2A = factory.createProduct2('5'); //2桁目の数値を表現する製品
AbstractSuper product2B = factory.createProduct2('A'); //2桁目の数値を表現する製品
AbstractProduct3 product3 = factory.createProduct3(); //合計を計算する製品
// 複数の抽象的な製品を用いた (複雑な) 手順でアウトプットを出す
product3.add(product1);
product3.add(product2A);
product3.add(product2B);
System.out.println(product3.task()); //F+50+A0=FF=255
}
}
Factory (抽象工場と抽象製品)
AbstractFactory.java
package factory;
public abstract class AbstractFactory {
public static AbstractFactory getFactory(String classname) {
AbstractFactory factory = null;
try {factory = (AbstractFactory)Class.forName(classname).newInstance();}
catch (Exception e) {e.printStackTrace();}
return factory;
}
public abstract AbstractProduct1 createProduct1(char digit);
public abstract AbstractProduct2 createProduct2(char digit);
public abstract AbstractProduct3 createProduct3();
}
AbstractSuper.java
package factory;
public abstract class AbstractSuper {
protected char digit;
public AbstractSuper(char digit) {this.digit=digit;}
public abstract int task();
}
AbstractProduct1.java
package factory; // 抽象クラスを継承する抽象クラス
public abstract class AbstractProduct1 extends AbstractSuper {
public AbstractProduct1(char digit) {super(digit);}
}
AbstractProduct2.java
package factory; // 抽象クラスを継承する抽象クラス
public abstract class AbstractProduct2 extends AbstractSuper {
public AbstractProduct2(char digit) {super(digit);}
}
AbstractProduct3.java
package factory;
import java.util.List;
import java.util.ArrayList;
public abstract class AbstractProduct3 {
protected List<AbstractSuper> list=new ArrayList<AbstractSuper>();
public void add(AbstractSuper abstractProduct) {list.add(abstractProduct);}
public abstract int task();
}
Concrete1 (具体的な工場および製品)
ConcreteFactory.java
package concrete1;
import factory.*;
public class ConcreteFactory extends AbstractFactory {
public AbstractProduct1 createProduct1(char digit) {return new ConcreteProduct1(digit);}
public AbstractProduct2 createProduct2(char digit) {return new ConcreteProduct2(digit);}
public AbstractProduct3 createProduct3() {return new ConcreteProduct3();}
}
ConcreteProduct1.java
package concrete1;
import factory.*;
public class ConcreteProduct1 extends AbstractProduct1 {
public ConcreteProduct1(char digit) {super(digit);}
public int task() {
if('0' <= digit && digit <= '9') return digit-'0';
else if ('A' <= digit && digit <= 'F') return digit-'A'+10;
else return -1;
}
}
ConcreteProduct2.java
package concrete1;
import factory.*;
public class ConcreteProduct2 extends AbstractProduct2 {
public ConcreteProduct2(char digit) {super(digit);}
public int task() {
if('0' <= digit && digit <= '9') return (digit-'0')*16;
else if ('A' <= digit && digit <= 'F') return (digit-'A'+10)*16;
else return -1;
}
}
ConcreteProduct3.java
package concrete1;
import factory.*;
import java.util.Iterator;
public class ConcreteProduct3 extends AbstractProduct3 {
public int task() {
int sum=0;
Iterator it = list.iterator();
while(it.hasNext()) sum += ((AbstractSuper)it.next()).task();
return sum;
}
}
実行例
$ javac sample.java factory/*.java concrete1/*.java && java Sample
255
記事の執筆者にステッカーを贈る
有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。
さらに詳しく →Feedbacks
ログインするとコメントを投稿できます。
関連記事
- Spring Security フォームログインのサンプルコードSpring フレームワークによる Web アプリケーション開発で、ログイン処理を実装する際は Spring Security が便利です。ここでは特に Spring Boot で Web アプリケーションを開発する場合を対象とし、フォームによる ID/Password ログインを行うためのサンプルコードをまとめます。 公式ドキュメント [Spring Security チュートリアル](http...
- Java配列の宣言方法 (C/C++との違い)Javaの配列 Javaの配列宣言方法はC/C++と似ているようで若干異なる。 初期化しない場合 C/C++の int array[10]; はJavaでは int array[] = new int[10]; となる。同様にC/C++の int array[3][3]; はJavaでは int array[][] = new int[3][3]; となる。 初期化
- PlantUML による UML 図の描き方PlantUML はテキスト形式で表現されたシーケンス図やクラス図といった UML (Unified Modeling Language) 図の情報から画像を生成するためのツールです。簡単な使い方をまとめます。 インストール方法の選択 Atom や Eclipse のプラグインをインストールしてエディタから利用する方法、JAR をダウンロードして Java コマンドで実行する方法、Redmine ...
- Akka HTTP サンプルコード (Scala)Akka アクターを用いて実装された汎用 HTTP フレームワークです。Spray の後継です。コアモジュールである akka-http-core は 2016/2/17 に experimental が外れました。akka-http などのいくつかのサブモジュールは 2016/3/1 現在 experimental のままですが、基本的な
- Kestrel の使用例Kestrel は Message Queue (MQ) の実装のひとつです。一般に MQ はアプリケーション間やプロセス間、スレッド間で非同期に通信するために用いられます。メッセージの送信側は MQ に書き込めば受信側の応答を待たずに次の処理に非同期に進むことができます。Kestrel はわずか 2500 行程の Scala で実装されており JVM で動作します。MQ 自体はメモリ上に存在する...