※部品というより製品って言った方がいいかもな・・・
まず、抽象的なPartは以下のような感じです。
- public abstract class Part {
- protected String name;
- public Part(String name) {
- this.name = name;
- }
- public abstract void doSomething();
- }
nameフィールドがprotectedになっていますが、これは子クラスでもnameフィールドにアクセス出来るようにするためです。
そのPartを扱うFactoryは以下のようにします。
- public abstract class Factory {
- public abstract Part createPart(String name);
- }
もし、種類の違うPartを用意したければ、Partクラスとは違うクラスを作成し、Factoryクラスの中にもう一つcreateメソッドを用意すればいいです(*1)
抽象的なクラスがあれば、具体的なクラスもあります(ようは、抽象的なクラスを継承したクラスを作るのです)。具体的なクラスは例として2種類用意しました。
まず、1つ目のABCPartは以下の感じです。doSomething()はとりあえずはnameを表示するだけにしました。
- import factory.Part;
- public class ABCPart extends Part {
- public ABCPart(String name) {
- super(name);
- }
- public void doSomething() {
- System.out.println("ABCPart - name: " + name);
- }
- }
- import factory.Factory;
- import factory.Part;
- public class ABCFactory extends Factory {
- public Part createPart (String name) {
- return new ABCPart(name);
- }
- }
- import factory.Part;
- public class DEFPart extends Part {
- public DEFPart(String name) {
- super(name);
- }
- public void doSomething() {
- System.out.println("DEFPartです。名前は " + name + " です。");
- }
- }
- import factory.Factory;
- import factory.Part;
- public class DEFFactory extends Factory {
- public Part createPart (String name) {
- return new DEFPart(name);
- }
- }
- import factory.Factory;
- import factory.Part;
- import abc_factory.ABCFactory;
- import def_factory.DEFFactory;
- public class Main {
- private static final String ABC_FACTORY = "ABCFactory";
- private static final String DEF_FACTORY = "DEFFactory";
- public static void main(String[] args) {
- // TODO argsの長さが0だったり、2以上の場合があるので、その時はSystem.exit(0)を呼んで終了させる。
- Factory factory = createFactory(args[0]);
- Part part = factory.createPart("sample");
- part.doSomething();
- }
- private static Factory createFactory(String factoryName) {
- if (ABC_FACTORY.equals(factoryName)) {
- return new ABCFactory();
- } else if (DEF_FACTORY.equals(factoryName)) {
- return new DEFFactory();
- } else {
- return null;// TODO こうすると呼び出し側でnullチェックをしないといけないので望ましくない。
- }
- }
- }
ということで、今回はFactoryも抽象化してみました。前回同様、具体的なことは知らなくても処理をすることができます。
ちなみに、Mainクラスは具体的なクラスをimport文を利用して知っちゃっています。Mainクラスも具体的なクラスを知らないようにする方法は以下のとおりです。
- public static Factory createFactory(String factoryName) {
- Factory factory = null;
- try {
- factory = (Factory)Class.forName(factoryName).newInstance();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- return factory;
- }
- }
関連パターン
「Builderパターン」どちらも複雑なインスタンスを生成するパターン
「Factory Methodパターン」FactoryクラスのcreateのところをFactory Methodパターンにすることがある。
「Compositeパターン」ファクトリーで作られる部品をComposite(つまり、部品の中に更なる部品)になる場合がある。
「Singletonパターン」ファクトリーをいくつ作っても仕方がないので、それをSingletonパターンにすることがある。
*1 なので、Factory Methodパターンを利用するのが良いかと
0 件のコメント:
コメントを投稿