22. • Uygulamamızın kalbinde duran çalışma mantığı her
yere sızma eğilimindedir. Bu yüzden çalışma
mantığındaki değişiklikleri yönetmek zorlayıcı olabilir.
• Altyapı bağımlılıkları değişiklik gösterebilir.
Problem?
@_mehmet_korkmaz
23. “Things do change. That's why we design and build with
change in mind”
Ron Jeffries
One of the three founders of the Extreme Programming,
Agile Founding Father
@_mehmet_korkmaz
25. • Bunların hepsi önemli olmakla beraber herbiri
uygulama detaylarıdır.
• Mimaride esas olan işleyiş mantığındaki (Domain)
ilişkilerdir.
Mimarideki Kritik Kararlar
Nelerdir?
@_mehmet_korkmaz
26. • Framework’den bağımsız olmalıdır.
• Veritabanından bağımsız olmalıdır.
• Harici servislerden bağımsız olmalıdır.
• Arayüzden bağımsız olmalıdır.
• Test edilebilir olmalıdır.
Nasıl olmalı?
@_mehmet_korkmaz
29. • Ports & Adapters
• Hexagonal Architecture
• Use Case Driven Architecture
@_mehmet_korkmaz
a.k.a
30. Alistair Cockburn
Computer Scientist, Agile Founding Father
“Allow an application to equally be driven by users,
programs, automated test or batch scripts, and to be
developed and tested in isolation from its eventual run-
time devices and databases.”
@_mehmet_korkmaz
32. • Application, Domain, ve Infrastructure birbirinden
net bir şekilde ayrılmalıdır.
• Bağımlılıklar Application ve Infrastructure’dan
Domain’e doğru olmalıdır.
• Sınırlar "Portlar ve Adaptörler” aracılığıyla birbirinden
izole edilmelidir.
Prensipler
@_mehmet_korkmaz
33. • Gerçek dünyada çözmeye çalıştığınız problemin
modelidir.
• Gerçek dünyada karşımıza çıkan kuralların modelidir.
• Gerçek dünyada karşımıza çıkan problemlerin
çözümünde aldığımız kararların modelidir.
Domain Nedir?
@_mehmet_korkmaz
34. • Uygulama içinde çalışma mantığına dair karar veren
kısımdır.
• Uygulamanın state’ini değiştirmeye dair yetkili tek
kısımdır.
• Uygulamanın içinde problem çözen kısımdır.
• Uygulamanın merkezindeki ilişkileri yöneten kısımdır.
Domain Layer Nedir?
@_mehmet_korkmaz
35. • Application Layer: Kullanıcı ve/veya diğer harici
uygulamaların uygulamamız ile etkileşime girdiği
katmandır.
• Domain Layer: Uygulamamızın çalışma mantığının yer
aldığı ve diğer katmanlarla nasıl etkileşime girileceğinin
belirlendiği katmandır.
• Infrastructure Layer: Uygulamızın implementasyon
detaylarının olduğu katmandır. Framework, veritabanı,
harici servisler vs.
Application, Domain, ve Infrastructure birbirinden
net bir şekilde ayrılmalıdır.
@_mehmet_korkmaz
39. • Application Layer Domain’i bir interface aracılığıyla
kullanır. (Ya da CQRS’deki Command’ları).
• Domain Layer da altyapıyı bir interface aracılığı ile kullanır.
• Bu interface’ler mimaride içeriden dışarıya açık yalıtım
aracı işlevi görür.
Sınırlar “Portlar ve Adaptörler” aracılığıyla
birbirinden izole edilmelidir.
@_mehmet_korkmaz
42. ~Domain Entity ~
@_mehmet_korkmaz
namespace MyApplicationDomainLog;
class Log
{
private $id;
private $logDate;
private $logMessage;
private $logContext;
private $createdAt;
public const LOG_TYPE = ‘LOGIN_ERROR’;
public function __construct(UUID $id, DateTime $logDate, string
$logMessage, array $logContext)
{
$this->createdAt = new Datetime();
//
}
}
43. ~Application Service Interface ~
@_mehmet_korkmaz
namespace MyApplicationDomainLog;
interface LogService
{
public function newLoginErrorLog(NewLoginErrorLogRequest $request) : bool;
}
44. ~Application Service ~
@_mehmet_korkmaz
namespace MyApplicationApplicationLog;
Use MyApplicationDomainLogLogService as DomainLogService;
class LogService implements DomainLogService;
{
private $logRepository;
public function __construct(LogRepository $logRepository)
{
private $this->logRepository = $logRepository;
}
public function newLoginErrorLog(NewLoginErrorLogRequest $request)
{
$log = LogFactory::createFromRequest($request);
$this->logRepository->save($log)
}
}
46. ~Domain LogRepository ~
@_mehmet_korkmaz
namespace MyApplicationDomainLog;
interface LogRepository
{
public function byId(UUID $id) : Log;
public function save(Log $log) : bool;
public function update(Log $log) : bool;
public function logList(string $logType, int $limit, int $skip) : LogCollection;
}
47. ~Infrastructure LogRepository ~
@_mehmet_korkmaz
namespace MyApplicationInfrastructurePersistenceLog;
use MyApplicationDomainLogLogRepository as LogRepositoryInterface;
class LogRepository implements LogRepositoryInterface
{
//
public function save(Log $log) : bool
{
$logDBData = [
‘log_date’ => $log->getLogDate()->format(‘Y-m-d H:i:s’),
‘message’ => $log->getMessage(),
‘type’ => $log->getLogType(),
//
];
$mongoCollection->insert($logDBData);
}
}
48. Use Case Controller
@_mehmet_korkmaz
namespace MyApplicationApplicationLog;
use MyApplicationApplicationLogLogService;
use PsrHttpMessageServerRequestInterface as Request;
use PsrHttpMessageResponseInterface as Response;
use RamseyUuidUuid;
class CreateNewLogController
{
public function __construct((LogService $logService));
public function __invoke(Request $request, Response $response)
{
$logData = $request->getParsedBody();
$logData[‘id’] = Uuid::uuid4();
$newLogRequest = new NewLoginErrorLogRequest(…$logData);
$this->logService->newLoginErrorLog($newLogRequest);
return $response->withAddedHeader(‘Location’, ‘/logs/’ . $logData[‘id’]);
}
}
50. “Psychologists have discovered that our minds are ruled
by two different systems—the rational mind and the
emotional mind—that compete for control. The rational
mind wants a great beach body; the emotional mind
wants that Oreo cookie. The rational mind wants to
change something at work; the emotional mind loves
the comfort of the existing routine. This tension can
doom a change effort—but if it is overcome, change
can come quickly.”
Preface from the book Switch: How to Change Things When Change Is Hard
by Chip and Dan Heath
@_mehmet_korkmaz
54. “Eğer doğru kullanırsanız, her araç silah olabilir”
Ani DiFranco
(Şarkıcı, şair, aktivist)
@_mehmet_korkmaz
Son olarak
55. 1. Cockburn, A. - https://web.archive.org/web/20090327032122/http://alistair.cockburn.us/
Hexagonal+architecture
2. Fowler, M. - https://martinfowler.com/bliki/PresentationDomainDataLayering.html
3. http://wiki.c2.com/?HexagonalArchitecture
4. Martin, R. C. https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
5. Alliaume, E. Roccaserra, S. https://blog.octo.com/en/hexagonal-architecture-three-principles-and-an-
implementation-example/
6. Graca, H. https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-
how-i-put-it-all-together/
7. Wynne, M. http://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/
8. Freeman, S. Pryce, N. Growing Object-Oriented Software, Guided by Tests
9. Vernon, V. Implementing Domain-Driven Design
10. Buenosvinos, C. Soronellas, C. Akbary K. Domain-Driven Design in PHP
References & Credits
@_mehmet_korkmaz