Last active
April 25, 2019 21:54
-
-
Save padge/1b2239145697456a3a4973d199d89a0c to your computer and use it in GitHub Desktop.
Cross Boundary Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Example of the Scheduling domain needing data from the User domain. | |
// ==================== | |
// User Domain | |
// ==================== | |
// User domain declares an application-level interface other contexts can reference. | |
// Currently in our app, these would just be the Commands and Queries inside the context. | |
// -- | |
// The objects returned should only contain data (DTO), and no behaviour. | |
// -- | |
// User/Application/IUserService.php | |
interface IUserService { | |
public function listUsers(ListUsersQuery $query): User[]; | |
public function createUser(CreateUserCommand $command): int; // would actually be a handler | |
} | |
// ==================== | |
// Scheduling Domain | |
// ==================== | |
// Scheduling declares it's own representation of a "User" with properties that make sense for scheduling. | |
// This is a value-object and shouldn't have it's own repository in scheduling. | |
// -- | |
// Scheduling/Domain/Employee.php | |
class Employee { | |
public $id; | |
public $name; | |
// etc. | |
} | |
// Scheduling domain defines an interface for the data it requires. | |
// -- | |
// Scheduling/Domain/IEmployeeService.php | |
interface IEmployeeService { | |
public function getEmployees(): Employee[]; | |
} | |
// Scheduling implements the IEmployeeService within it's infrastructure layer. | |
// The implementation queries the Scheduling domain, and maps the User data into it's own value object. | |
// -- | |
// Scheduling/Infrastructure/EmployeeService.php | |
class EmployeeService implements IEmployeeService { | |
/** @var IUserService from User context. */ | |
private $user_service; | |
public function getEmployees(): Employee[] { | |
$users = $this->user_service->listUsers(new ListUsersQuery()); | |
// Eventually this could be: | |
// $users = $this->client->get('/api/v2/users'); | |
return array_map([$this->employee_mapper, 'fromUser'], $users); | |
} | |
} | |
// Now scheduling services can depend on the new employee service, | |
// rather than couple to User code directly, or bloat User code with | |
// logic specific to the scheduling domain. | |
// -- | |
// Scheduling/Application/SomeSchedulingService.php | |
class SomeSchedulingService { | |
/** @var IEmployeeService */ | |
private $employee_service; | |
public function someSchedulingAction() { | |
$employees = $this->employee_service->getEmployees(); | |
// do something w/ employees | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment