リスト2は、Chain of Responsibilityパターンの中核となるApprover(承認者)クラスです。Approverクラスでは、このデザインパターンにおける既知のエンティティがHandlerとして表現されています。これは一般に抽象クラスであり、具体的には、この例で実装することに決めたManager、VicePresident、CEO(リスト3を参照)の3種類のハンドラサブタイプのいずれかを表します。この他にAutoRejectHandlerも存在します。このタイプの承認者は何もかも拒否します。
クライアントは、handleメソッドを用いて、ExpenseReportオブジェクトをApproverへ送ります。handleメソッドのコードでは報告書の転送と承認のどちらを行うかが決定されます。報告書が転送されるのは、承認者にそれを処置する権限がない(具体的には金額が大きすぎるか、海外旅行の決済が許可されていない)場合と、承認者が不在の場合です。
public class Approver {
private Approver nextApprover;
private int dollarLimit;
private boolean isOutOfOffice;
private boolean canApproveInternational;
private final String name;
public Approver(String name, boolean canApproveInternational,
int dollarLimit) {
this.name = name;
this.canApproveInternational = canApproveInternational;
this.dollarLimit = dollarLimit;
}
public String getName() {
return name;
}
public void handle(ExpenseReport report) {
if (!canApprove(report) || isOutOfOffice())
nextApprover.handle(report);
else
report.approve(this);
}
private boolean canApprove(ExpenseReport report) {
return report.getTotalDollarAmount() <=
getDollarLimit() &&
(canApproveInternational() ||
!report.isInternationalTravel());
}
public void setNextApprover(Approver approver) {
nextApprover = approver;
}
public boolean isOutOfOffice() {
return isOutOfOffice;
}
public void setOutOfOffice(boolean isOutOfOffice) {
this.isOutOfOffice = isOutOfOffice;
}
public int getDollarLimit() {
return dollarLimit;
}
public boolean canApproveInternational() {
return canApproveInternational;
}
public void setCanApproveInternational(boolean
canApproveInternational) { this.canApproveInternational =
canApproveInternational;
}
}
Approverの各サブクラスでは、承認の詳細な制約が定義されます。管理者(Manager)が承認できる限度額は5,000ドルで、一部の管理者は海外旅行も承認できます。副社長(VicePresident)が承認できる限度額は100,000ドルで、すべての海外旅行を承認できます。CEOは、不在でない限り、何もかも承認できます。CEOが不在の場合、経費報告書は残念ながら自動的にAutoRejectHandlerへ送られます。
public class Manager extends Approver {
private static final int APPROVAL_LIMIT = 5000;
public Manager(String name, boolean canApproveInternational) {
super(name, canApproveInternational, APPROVAL_LIMIT);
}
}
public class VicePresident extends Approver {
private static final int APPROVAL_LIMIT = 100000;
public VicePresident(String name) {
super(name, true, APPROVAL_LIMIT);
}
}
public class CEO extends Approver {
private static final int APPROVAL_LIMIT = Integer.MAX_VALUE;
public CEO(String name) {
super(name, true, APPROVAL_LIMIT);
setNextApprover(new AutoRejectHandler());
}
}
public class AutoRejectHandler extends Approver {
public AutoRejectHandler() {
super("auto-reject", false, 0);
}
@Override
public void handle(ExpenseReport report) {
report.reject();
}
}
この記事は参考になりましたか?
- デザインパターンの使い方連載記事一覧
- この記事の著者
-
japan.internet.com(ジャパンインターネットコム)
japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.com や EarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
Jeff Langr(Jeff Langr)
本格的なソフトウェアの開発に四半世紀以上携わってきたベテランのソフトウェア開発者。『Agile Java: Crafting Code With Test-Driven Development』(Prentice Hall、2005年)と、他の1冊の著書がある。『Clean Code』(Uncle Bob Martin著、Prentice Hall、2008年8月)にも寄稿している。また、ソフトウェア開発に関する記事を80件以上執筆しており、そのうちの...
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
