インスタンス生成の分岐: Factory method の細工

stuff → staff

続き: インスタンス生成の分岐: factory method パターン - Red > Green > Refactor > Red

f:id:mat5ukawa:20150917222745p:plain

  • ダメ 私に響かない
    • クライアント側で冗長な情報が必要
      • パッケージ名、サブクラス名は公開せねばならぬし
      • (jdbc の悪夢)
    • プロダクション側でインスタンス生成の柔軟対応不可
src
  |
  +-- jp.ymatsukawa
      +-- Main.java
      |
      +-- stuff
           |
           + -- Creator.java
           + -- Stuff.java
           + -- Manager.java
           + -- Engineer.java

jp.ymatsukawa/Main.java

package jp.ymatsukawa;

import jp.ymatsukawa.stuff.Creator;
import jp.ymatsukawa.stuff.Stuff;

public class Main {
  public static void main(String[] args) {
    Creator stuffCreator = new Creator();
    Stuff manager  = stuffCreator.create("jp.ymatsukawa.stuff.Manager");
    Stuff engineer = stuffCreator.create("jp.ymatsukawa.stuff.Engineer");
    System.out.println(manager.getMonthlySalary());  // 40
    System.out.println(engineer.getMonthlySalary()); // 30
  }
}

jp.ymatsukawa/stuff/Creator.java

package jp.ymatsukawa.stuff;

public class Creator {
  public Stuff create(String stuffType) {
    try {
      return (Stuff)Class.forName(stuffType).newInstance();
    } catch (Exception e) {
      e.printStackTrace();
      throw new IllegalArgumentException("Invalid stuff type");
    }
  }
}

jp.ymatsukawa/stuff/Stuff.java

package jp.ymatsukawa.stuff;

public abstract class Stuff {
  private final int baseSalary = 20;
  public abstract int getMonthlySalary();
  protected int getBaseSalary() {
    return this.baseSalary;
  }
}

jp.ymatsukawa/stuff/Manager.java

package jp.ymatsukawa.stuff;

public class Manager extends Stuff {
  public int getMonthlySalary() {
    return this.getBaseSalary() + 20;
  }
}

jp.ymatsukawa/stuff/Engineer.java

package jp.ymatsukawa.stuff;

public class Engineer extends Stuff {
  public int getMonthlySalary() {
    return this.getBaseSalary() + 10;
  }
}

stackoverflow.com