Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Recommended Posts

Ola galera

 

Tenho pesquisado muito sobre este assunto na internet, e durante estas pesquisa descobri que uma Entidade possui uma identidade, já o Value Object não possui uma identidade. Queria saber isso na prática(no código) como seria essa "identidade" no decorrer de um projeto, agradeço desde já

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu entendo que a identidade de uma Entidade seja o conjunto dos atributos utilizados no mundo virtual.

Ex: no mundo real temos a Entidade carro, com os seguintes atributos: cor, ano, modelo, potencia, etc...

No mundo virtual temos para esta Entidade, uma identidade com estes atributos de forma literal.

 

Carro

string cor

int ano

string modelo

 

os objetos são frutos dessas identidades, uma vez que cada objeto é originário de uma classe que possui tais atributos.

 

Ex: a classe carro pode gerar n's carros com valores distintos em seus atributos

 

carro1

cor vermelha

ano 2001

modelo gol

 

carro2

cor azul

ano 2015

modelo celta

 

etc..

Compartilhar este post


Link para o post
Compartilhar em outros sites

Atributos definem um estado e são mutáveis. Identidade não é mutável, é única.

Entretanto, um ValueObject (VO) tem seu estado, de certa forma, imutável. Toda a vez que você tentar alterar o estado de um VO, você receberá uma nova instância do mesmo objeto com o seu novo estado.

Você deve entender que Entity e ValueObject são padrões de estrutura. A Entity é utilizada para definir um object de negócio normalmente, não sempre, associado a um storage.

Já o ValueObject, tem como intuito impedir a cópia por referência. O que normalmente ocorre com objetos que representam dinheiro ou hora.

Por exemplo:

function showNextDay(\DateTimeInterface $dateTime) {
    $dateTime->add(new \DateInterval('P1D'));
    echo $dateTime->format('d/m/Y');
}

Uso:

$now = new \DateTime(); 

echo $now->format('d/m/Y');

showNextDay($now);

echo $now->format('d/m/Y');

Saída:

22/09/2015
23/09/2015
23/09/2015 //Valor alterado pela referência

Agora, utilizando um ValueObject (é necessária alterar a implementação da function showNextDay():

function showNextDay(\DateTimeInterface $dateTime) {
    echo $dateTime->add(new \DateInterval('P1D'))->format('d/m/Y');
}

Uso:

$now = new \DateTimeImmutable();

echo $now->format('d/m/Y');

showNextDay($now);

echo $now->format('d/m/Y');

Saída:

22/09/2015
23/09/2015
22/09/2015

Compartilhar este post


Link para o post
Compartilhar em outros sites

Depois percebi que esqueci de mencionar sobre a identidade.

 

A diferença entre ambos, sobre identidade, é a forma para se verificar que um objeto é igual ao outro.

 

Em um Entity, pode ser usado '===' normalmente. Mas em um ValueObject, essa abordagem não funciona.

 

Entretanto, utilizando o exemplo de dinheiro, R$ 5,00 são tão bons, e iguais, quanto qualquer outros R$ 5,00. Ou seja, uma nota de R$ 5,00 é tão bom quanto 5 moedas de R$ 1,00 (isso em questões de valores, não vamos considerar peso/volume :lol: )

 

Então veja só:

<?php


class Money {

    private $value;

    /**
     * @param int|float
     **/
    public function __construct($value) {
        if(!is_numeric($value)) {
            throw new \UnexpectedValueException('Only numeric values are accepted');
        }
      
        $this->value = $value;
    }
  
    public function getValue() {
        return $this->value;
    }
  
    public function add(\Money $money) {
        return new self($this->getValue() + $money->getValue());
    }
  
    public function remove(\Money $money) {
        return new self($this->getValue() - $money->getValue());
    }
  
    public function isEqual(\Money $money) {
        return (boolean)($this->getValue() == $money->getValue());
    }
}
Temos nossa classe Money implementada, vamos ao seu uso:

$money = new Money(5.00);

$cofrinho = new Money(0);
$cofrinho100 = $cofrinho->add(new Money(1));
$cofrinho150 = $cofrinho100->add(new Money(0.50));
$cofrinho300 = $cofrinho150->add(new Money(1.50));
$cofrinho500 = $cofrinho300->add(new Money(2.00));

var_dump($money == $cofrinho);//False, não possuem o mesmo estado
var_dump($money == $cofrinho500);//True, possuem o mesmo estado
var_dump($money === $cofrinho);//False, não são os mesmos objetos
var_dump($money === $cofrinho500);//False, não são os mesmos objetos

var_dump($money->isEqual($cofrinho500));//True
Assim, como na vida real, quando você "junta" o dinheiro, você não deixa de ter o dinheiro original (quantidade/valores de notas e/ou moedas), mas possui um novo montante.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Obrigado pelas explicações @rnu.silva, @Gabriel Heming


Gabriel perfeito o seus exemplos, entendi perfeitamente. Mas só uma dúvida você falou que nos padrões value objects, o que importa e o seu estado(os seus atributos) né?! então se caso o dinheiro tivesse outro atributo chamado de "tipo_de_material"(papel, moeda e etc..), nesse caso um montante de R$5,00 de papel seria diferente de um montante de R$5,00 de moeda, certo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não, o montante de R$ 5,00 é igual em qualquer tipo físico (ou digital). Se eu adicionasse o atributo de tipo, o método isEqual deve considerar apenas o valor.

 

 

 

Dessa forma, o '==' passaria a ser false (em alguns casos) e apenas o isEqual seria parâmetro para comparação.

 

Apesar de possuirem estados diferente, economicamente falando, R$ 5,00 em moedas são tão bons quanto qualquer outros R$ 5,00.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por JosimarNew
      Olá amigos, segue em anexo um diagrama onde faço o relacionamento entre entidades, subentidades e atributos. Gostaria que pessoas mais experientes comentassem e me apresentassem um senso crítico a respeito.
       
       
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.