既存の処理に特定の条件の時だけ実行する処理を追加したい、
従来のパフォーマンスに影響は出したくない、条件は後から増えそう…
って時にNullObjectパターンとTemplateMethodパターンを使うと捗るというお話。
まず追加処理のインタフェース。
Service.java
public interface Service {
public void execute();
}
追加処理は別スレッドでやらせたいので、抽象クラスで共通化する。
AbstractService.java
public abstract class AbstractService implements Service {
private final ExecutorService threadPool = Executors.newCachedThreadPool();
@Override
public void execute() {
threadPool.submit(new Runnable() {
@Override
public void run() {
executeInternal();
}
});
}
public abstract void executeInternal();
}
追加処理の中身を実装。ここまでTemplateMethodパターン。
HogeService.java
public class HogeService extends AbstractService {
@Override
public void executeInternal() {
System.out.print("hoge");
}
}
条件分岐で実行する処理を決定。ここでNullObjectパターンの出番。
Factory.java
public class Factory {
private final NullService nullService = new NullService();
@Inject
private HogeService hogeService;
public Service getService(int type) {
switch (type) {
case 1:
return hogeService;
case 2:
default:
return nullService;
}
}
private class NullService implements Service {
@Override
public void execute() { }
}
}
既存の処理に追加して完成。
Controller.java
public class Controller {
@Inject
private Factory factory;
public void hoge() {
// 既存の処理
int type = 1;
System.out.print("hoge");
// 追加する処理
Service service = factory.getService(type);
service.execute();
}
public void fuga() {
// 既存の処理
int type = 2;
System.out.print("fuga");
// 追加する処理
Service service = factory.getService(type);
service.execute();
}
}
Controller#hoge()は「hogehoge」と表示され、Controller#fuga()は「fuga」と表示される。