DDDにおいてDBの停止状態をチェックするのはどのレイヤーか
DDDをベースに web アプリケーションの設計を進めていて、DBの停止状態(メンテナンス等による一時休止)をどのレイヤーでチェックし、停止時/非停止時で処理を分岐させたら良いか悩んでいます。
私の理解だと、「DBMSの稼働状態、また状態による処理の分岐」はアプリケーションレイヤーが持つべき責務で、これらの処理はコントローラー等に実装するのがいいと思ってます。ただ、実際にDBの状態をチェックし処理を分岐させる必要があるのは、リポジトリー経由でモデルを生成/保存するタイミングであり、リポジトリーを呼び出す際にコントローラー側でいちいち DB の状態をチェックするというのは、DRY の観点からも良くないと感じています。リポジトリーに「DB の状態をチェックせずに呼び出してはいけない」という事前条件を付与するのは、かなり危険です。
この観点から、DataBase の抽象クラスをインフラアーキテクチャレイヤーに作成し、リポジトリーに渡す設計を考えました。Database の具象クラスはアプリケーションレイヤーに実装します。
以下 PHP を例にとって実装例を挙げます。
インフラアーキテクチャレイヤー
namespace sample\infra;
abstract class Database {
public function __construct() {
if($this->is_maintenance()) {
throw new \Exception;
}
}
abstract protected function is_maintenance();
}
アプリケーションレイヤー
namespace sample\application;
class HogeMasterDatabase extends \sample\infra\Database {
protected function is_maintenance() { /* */ }
}
class HogeSlaveDatabase extends \sample\infra\Database {
protected function is_maintenance() { /* */ }
}
class HogeController {
public function read() {
$slave = new HogeSlaveDatabase; //ここの例外はRouter等でキャッチする
$repository = new \sample\domain\HogeRepository($slave);
$hoge = $repository->fetch($id);
// カウンターをインクリメント
try {
$master = new HogeMasterDatabase;
$repository = new \sample\domain\HogeRepository($master);
$factory = new HogeFactory($hoge);
$factory->setCounter(++$hoge->getCounter());
$repository->update($factory->create());
} catch (\Exception $e) {
// masterがメンテナンスの時は無視する
}
}
}
ドメインレイヤー
namespace sample\domain;
class Hoge {
private $counter;
public function getCounter() {
return $this->counter;
}
}
class HogeRepository {
private $db;
public function __construct(\sample\infra\Database $db) {
$this->db = $db;
}
public function fetch($id) { }
public function update(Hoge $model) { }
}
こういったケースでは、どう設計&実装すべきでしょうか。アドバイスを頂けると嬉しいです。