We are designing web applications based on DDD, and we are wondering which layer to check DB outage (pause due to maintenance, etc.) and branch the process when stopped/non-disruptive.
"My understanding is that ""branching processing according to DBMS operational state and state"" is the responsibility of the application layer, and it is better to implement these processing on controllers, etc."However, I think it is not good from DRY's point of view to check DB status one by one when the model is generated/saved through the repository, and it is not good for the controller to check DB status one by one when calling the repository.Giving a repository a precondition that says, "Don't call without checking the state of the DB" is quite dangerous.
From this point of view, we considered a design to create an abstract DataBase class in the infrastructure architecture layer and pass it to the repository.Implement Database classes in the application layer.
The following is an example implementation of PHP:
Infrastructure Architecture Layer
namespace sample\infra;
abstract class Database {
public function__construct(){
if($this->is_maintenance()){
through new\Exception;
}
}
abstract protected function is_maintenance();
}
Application Layer
namespace sample\application;
class HogeMasterDatabase extensions\sample\infra\Database{
protected function is_maintenance() {/**/}
}
class HogeSlaveDatabase extensions\sample\infra\Database{
protected function is_maintenance() {/**/}
}
class HogeController {
public function read() {
$slave = new HogeSlaveDatabase;// Exceptions here are caught on Router, etc.
$repository=new\sample\domain\HogeRepository($slave);
$hoge = $repository->fetch($id);
// Increment the counter
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){
// Ignore master for maintenance
}
}
}
Domain Layer
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){}
}
In these cases, how should we design & implement it?I'd appreciate it if you could give me some advice.
php domain-driven-design
It depends on the application's policy which layer handles DB exceptions, but at least it will not be directly managed by the domain layer repository.It will be managed in some kind of use case.It doesn't matter which layer this use case belongs to.
The state of the database probably requires common behavior throughout the application.In addition to the approach of writing conditional branches to individual controllers as described in the question, there are many other options.
If there are some procedures, such as determining by master/slave, such as the code written in the question, the second template method will be easy to understand.
Recent PHP uses Closure, which allows you to define and pass DB state-dependent actions in Closure.As an example of doing something similar, you may find the framework Ravel's mechanism for blocking transactions helpful.
P.S. I think this is a question about application or framework design in general regardless of domain-driven design.
I think the implementation details are too much in the first place to practice DDD.With DDD, it's important to speak "Ubiquitous Language" before you go into design or implementation details.
What does the ubiquitous language of the business domain talk about in response to the DB outage situation?The outage should have some effect on the behavior of the domain, but how does the ubiquitous language talk about the impact?
DB outage is a completely unexpected event in ubiquitous language, and the behavior at that time is completely undefined?If so, it's not a domain concern, so you can check at the infrastructure layer and throw system errors into the application layer.
If the ubiquitous language has any words to say about the situation, it should be incorporated into the domain model as it is a domain layer concern.
You can check within the repository implementation class.As a layer, I think it will be infrastructure.
© 2024 OneMinuteCode. All rights reserved.