Skip to content

Instantly share code, notes, and snippets.

@padge
Last active April 25, 2019 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save padge/1b2239145697456a3a4973d199d89a0c to your computer and use it in GitHub Desktop.
Save padge/1b2239145697456a3a4973d199d89a0c to your computer and use it in GitHub Desktop.
Cross Boundary Example
<?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