Valores e entidades
A distinção que decide metade da modelagem — e como cada lado é cobrado.
Duas pessoas com o mesmo nome são duas pessoas. E a mesma pessoa com outro nome continua sendo ela. O que separa uma entidade de um objeto de valor não é a mutabilidade — é a continuidade.
Objeto de valor#
steady Dinheiro := D.valor("Dinheiro", ["quantia", "moeda"],
regra := lambda v => v["quantia"] bigger_eq 0,
motivo := "dinheiro nao e negativo")
dez := Dinheiro(10, "BRL")
outro := Dinheiro(10, "BRL")
assert dez is outro // o MESMO valor
vinte := dez.com(quantia := 20) // outro valor; o original nao muda
assert dez.quantia is 10O record da linguagem já dá a imutabilidade e a igualdade estrutural, e essas duas metades são a maior parte. O que ele não dá é a regra: um Dinheiro(-5, "BRL") é um record perfeitamente válido, e o negócio descobre isso três camadas adiante, num extrato negativo.
Uma regra que estoura não vira "valor inválido": ela vira um erro dizendo que a regra quebrou. Dizer "inválido" ali esconderia o defeito real, que é da regra e não do valor.
Entidade#
ana := D.entidade("Pessoa", "1", nome := "Ana")
ana_maria := D.entidade("Pessoa", "1", nome := "Ana Maria")
homonima := D.entidade("Pessoa", "2", nome := "Ana")
assert ana is ana_maria // mesma id, outro nome -> a mesma pessoa
assert ana isnt homonima // mesmo nome, outra id -> duas pessoasO identificador é texto, e nasce com o objeto (D.novo_id() dá um UUID4). Um id que o banco gera obriga a salvar antes de ter identidade — e no intervalo entre criar e confirmar o objeto existe sem ser ele mesmo.
E um valor não entra num repositório#
D.repositorio("Dinheiro").guardar(Dinheiro(10, "BRL"))
// erro: o que vai para um repositorio precisa de identidadeNão é uma limitação: é a distinção sendo cobrada. Se a sua peça precisa distinguir duas instâncias iguais, ela é uma entidade — e o módulo diz isso em vez de deixar passar.