Este documento discute Domain-Driven Design (DDD), uma abordagem para desenvolvimento de software focada no modelo de negócios. DDD enfatiza a importância de encapsular as regras de negócio e desenvolver um modelo de domínio que represente claramente os conceitos centrais do negócio.
2. pen4education
Domain-Driven Design?
Domain-Driven Design é uma abordagem para o Desenvolvimento de Software que estabelece uma
forte ligação entre a implementação e o modelo evolutivo dos conceitos de negócio. Implementação X
Negócios
4. pen4education
Fundamentação
“Vai escrevendo código
ai, quando precisar
coloque na camada de
apresentação, no
banco de dados nos
controles, modelos, na
configuração do
webserver e não
esquece do xml e
aquele if maroto no
APPLICATION_ENV”
10. pen4education
Orientação a Objetos
Quando pensamos em POO logo
pensamos em Classes, Encapsulamento,
Polimorfismo, Herança...
POO é mais que isso, a essência da
POO é alinhamento do código com o
negócio, reutilização, mínimo de
acoplamento, linguagem natural...
14. pen4education
Linguagem Ubíqua
Definições de Ubíqua
“O termo foi usado pela primeira vez pelo cientista Norte-Americano Mark Weiser
em 1988 e publicado em 1991 no seu artigo The Computer for the 21st Century”
“termo usado para descrever a onipresença da informática no cotidiano das
pessoas”
“Computação ubíqua tem como objetivo tornar a interação homem computador
invisível, ou seja, integrar a informática com as ações e comportamentos naturais
das pessoas”
Para que um software atenda um domínio, é necessário que se estabeleça, em
primeiro lugar, uma linguagem Ubíquia ou seja, linguagem comum, com termos
bem definidos, que fazem parte do domínio do negócio e que são usados por
todas as pessoas que fazem parte do processo de desenvolvimento.
15. pen4education
Model Driven Design
Projeto Dirigido pelo Modelo (Model Driven Design – MDD). A ideia por
trás de MDD é a de que o seu modelo abstrato deve ser uma representação
perfeita do seu domínio.
O MDD defende o processo
ágil, o trabalho em equipe
ou seja, especialistas em
negócio, desenvolvedores e
arquitetos trabalhando
juntos.
Diagramas da UML ajudam
o entedimento do domínio.
16. pen4education
Blocos de Construção
Encapsulando o modelo de domínio.
Interface de Usuário – Interação com o
usuário;
Aplicação – essa camada não possui lógica de
negócio. Ela é apenas uma camada fina,
responsável por conectar a Interface de Usuário às
camadas inferiores;
Domínio – representa os conceitos, regras
e lógicas de negócio. Todo o foco de DDD
está nessa camada. Nosso trabalho, daqui
para frente, será aperfeiçoar e compreender
profundamente essa parte;
Infra-estrutura – fornece recursos técnicos que
darão suporte às camadas superiores. São
normalmente as partes de um sistema
responsáveis por persistência de dados, conexões
com bancos de dados, etc.
18. pen4education
Entidades
<?php
class Exercicio_Negocio_Exercicio {
private $id;
private $nome;
private $descricao;
private $exercicioMercanismo;
private $autocorreção;
public function getExercicioMercanismo() {
if ($this->exercicioMecanismo == null && $this->entidadeValida()) {
$elementDAO = Exercicio_Infraestrutura_Model_Dao_ExercicioDAOFactory::getInstance()->getExercicioDAO();
$this->exercicioMecanismo = $elementDAO->getMecanismoExercicio($this);
}
return $this->exercicioMercanismo;
}
public function gravar()
{
$exercicioDAO = Exercicio_Infraestrutura_Model_Dao_ExercicioDAOFactory::getInstance()->getExercicioDAO();
return $exercicioDAO->persist($this);
}
public function getExercicioConteudo(ACSNegocioNucleoUsuario $usuario)
{
return Exercicio_Negocio_ExercicioConteudo::buscarPorUsuarioExercicio($this, $usuario);
}
private function entidadeValida() {
$entidadeValida = false;
if ($this->getId() != null) {
$entidadeValida = true;
}
return $entidadeValida;
}
}
19. pen4education
Objetos de valor
Muitos objetos não possuem nenhuma identidade conceitual. Esses objetos descrevem alguma
característica de alguma coisa.
20. pen4education
Objetos de valor
<?php
namespace ProductModelVo;
class Price
{
Const CURRENCY = 'R$';
private $price;
private $discountPercentage;
private $discount;
// get's and set's
public function getPrice()
{
// business rules to return price
}
public function setSpecialPrice($setSpecialPrice)
{
if ($specialPrice >= $this->getPrice()) {
$specialPrice = null;
}
$this->specialPrice = $specialPrice;
}
public function setSpecialPriceComparison($specialPriceComparison)
{
$this->specialPriceComparison = $specialPriceComparison;
if ($this->verifyPriceComparison()) {
$this->setSpecialPrice($specialPriceComparison);
}
}
private function verifyPriceComparison()
{
// verify channels...
}
}
21. pen4education
Serviços
Ás vezes, a situação simplesmente não se trata de alguma coisa.
Em algums casos, um design mais limpo e mais pragmático inclui operações que não pertencem
conceitualmente a nenhum objeto. Em vez de forçar a questão, podemos seguir os limites naturais do espaço
do problema e incluir SERVIÇOS explicitamente no modelo.
22. pen4education
Serviços
<?php
namespace ProductService;
class Catalog {
Const BALANCE_STANDARD_STOCK = 0;
protected $catalogRepo;
public function __construct(RepositoryInterface $catalogRepo)
{
$this->catalogRepo = $catalogRepo;
}
public function getBalanceStock(Item $item)
{
$balanceStock = self::BALANCE_STANDARD_STOCK;
$stockReserved = $this->catalogRepo->getQuantityReservedStock($item);
$currentBalance = (int) ($item->getQuantity() - $stockReserved);
if ($currentBalance > $balanceStock) {
$balanceStock = $currentBalance;
}
return $balanceStock;
}
}
23. pen4education
Agregados
O design detalhado de associações ajuda a simplificar um comportamento de um objeto mas, em
diversos casos, existe a necessidade de explorar a modelagem se adequando com o domínio complexo.
24. pen4education
Agregados
<?php
namespace ProductModelAggregate;
class Product extents AbstractProduct
{
/** @var ProductModelVoPrice */
protected $price;
/** @var ProductModelCollectionItem */
protected $itemCollection;
public function getItemCollection()
{
if ($this->hasItemCollection() && $this->getIdentification()) {
$this->setItemCollection($this->getProductService()->getItemCollectionByIdentification($this->getIdentification()));
}
}
public function hasItemCollection()
{
$hasItemCollection = false;
if ($this->ItemCollection) {
if ($this->ItemCollection instanceof ProductModelCollectionItem) {
$hasItemCollection = true;
}
}
}
public function getQuantity()
{
$quantity = 0;
if (($this->hasItemCollection()) && ($this->ItemCollection->count() >= 1)) {
$quantity = $this->calculateQuantity();
}
return $quantity;
}
}
25. pen4education
Fábricas
Quando a criação de um objeto ou um AGREGADO inteiro se torna complicada ou revela uma grande
parte de estrutura interna, as FÁBRICAS fornecem o encapsulamento.
26. pen4education
Fábricas
class OrderFactory{
public static function createOrder(ICustomer $customer, ProductCollection $productCollection) {
$order = new Order($customer, $productCollection);
$customerPayment = PaymentFactory::createCustomerPayment($customer);
if ($customerPayment->hasRecurrent()) {
$order->setPayment($customerPayment)
}
return $order;
}
}
27. pen4education
Repositórios
Associações nos permitem achar um objeto baseado em sua relação com outro objeto. Mas é preciso ter
um ponto de partida para uma travessia até uma ENTIDADE ou um VALOR no meio do seu ciclo de vida.
28. pen4education
Repositórios
<?php
namespace ApplicationModel;
class ConfigurationRepository implements RepositoryInterface
{
protected $dataMapper = null;
protected $entityContext;
public function __constuct(DataMapper $dataMapper)
{
$this->dataMapper = $dataMapper;
$this->dataMapper->entityContext($this->getEntityContext());
}
public function findAll()
{
return $this->dataMapper->listAll();
}
public function findById($id)
{
$configurationEntity = false;
$configurations = $this->dataMapper->findBy(array('id' => $id));
if ($configurations) {
$configurationEntity = $configurations->current();
}
return $configurationEntity;
}
}