DDD - Value Object

[quote=mochuara][quote=esmiralha]http://dddsample.sourceforge.net/characterization.html#Value_Objects
O projeto é do Eric Evans, ok?

http://dddsample.sourceforge.net/xref/se/citerus/dddsample/domain/model/cargo/Leg.html

Leg é um VO (implementa ValueObject) e referencia (“contém um private member do tipo de”) 2 Locations (implementa Entity) e 1 Voyage (implementa Entity).

[/quote]

Repare que Location e Voyage são imutáveis, o que não representa um perigo neste exemplo de livro. [/quote]

Repare que Cargo é mutável, é referenciado por HandlingEvent, que por sua vez é referenciado por Delivery (VO).

Haanh?
Eu acho que você quer é confusão por que não explica nada e ainda tenta confundir mais!

Provavelmente vc está certo e há falha não está no DDD, e sim nas linguagens OO.

[quote]People accustomed to OO conceive of their programs as mutating the values of objects. They understand the true notion of a value, say, 42, as something that would never change, but usually don’t extend that notion of value to their object’s state. That is a failure of their programming language. These languages use the same constructs for modeling values as they do for identities, objects, and default to mutability, causing all but the most disciplined programmers to create many more identities than they should, creating identities out of things that should be values etc.
[/quote]

http://clojure.org/state

Ou talvez a falha esteja em seu código genético.

Cara não da mais confiança que deu para ver que esse é troll de internet, eu que fui trouxa e pensava que estava numa discussão séria!

Pelo visto esgotou o estoque de citacoes?

e o troll ataca novamente…ele não veio para esclarecer e sim para confundir… :slight_smile:

Seu objeto imutavel é na verdade mutável, apenas haja de acordo.

Seu objeto imutavel é na verdade mutável, apenas haja de acordo.

[/quote]
Então porque o presente Troll não explica para nós simples mortais qual o significado de imutabilidade que o Evans fala? Explique também o que ele quis dizer com um OBJETO VALOR com referências a ENTIDADES? Não diz ou porque não sabe ou porque veio para confundir não para esclarecer.
Pessoal já notou que até agora o grande Troll mochuara não explicou nada, só falou que os outros estão errados? Qual a finalidade disso afinal?

Seu objeto imutavel é na verdade mutável, apenas haja de acordo.

[/quote]
Então porque o presente Troll não explica para nós simples mortais qual o significado de imutabilidade que o Evans fala? Explique também o que ele quis dizer com um OBJETO VALOR com referências a ENTIDADES? Não diz ou porque não sabe ou porque veio para confundir não para esclarecer.
Pessoal já notou que até agora o grande Troll mochuara não explicou nada, só falou que os outros estão errados? Qual a finalidade disso afinal?[/quote]

Este é um fórum gratuito, ninguém te deve nada, nem mesmo explicações.

Sobre o tema em questão, se possui uma definição propria de imutabilidade diferente da oficial que é não permitir um objeto ser alterado por nenhuma thread então nos diga.

Eu gosto de exemplos:

[code]class A {
private String nome;

public A(String nome) {this.nome = nome;}
public String getNome() { return nome; }
}
[/code]

poderia dizer que ele é imutável

[code]class B {
private int codigo;
private String nome;

public B(int codigo, String nome) {this.codigo = codigo; this.nome = nome;}
public int getCodigo() { return codigo; }
public String getNome() { return nome; }
public void setNome(String nome) { this.nome = nome; }
}
[/code]

B objB = new B(1, "imutavel"); objB.setNome("mudou");
não é imutável

[code]class C {
private String nome;
private B b;

public C(String nome, B b) {this.nome = nome; this.b = b;}
public String getNome() { return nome; }
public B getB() {return b; }
}
[/code]
poderia dizer que ele é imutável?

B objB = new B(1, "mutavel"); C objC = new C("imutavel?", objB);
não posso alterar diretamente C, mas alterando B, C é alterado.
um objeto para ser considerado imutável, tem de garantir que todos os objetos que ele referencia tb são?

Porém se B tiver o hashCode e equals, definidos usando-se apenas o codigo (que não é alterado) ele seria imutável ou mutável?

[code]class Imutavel {
private Mutavel _m;

public Imutavel(Mutavel m) {
this._m = m.clone();
}

public Mutavel getM() {
return this._m.clone();
}
}[/code]

[quote=mochuara]Este é um fórum gratuito, ninguém te deve nada, nem mesmo explicações.

Sobre o tema em questão, se possui uma definição propria de imutabilidade diferente da oficial que é não permitir um objeto ser alterado por nenhuma thread então nos diga. [/quote]
Pera ai eu nunca disse que um objeto valor poderia ser alterado por outro objeto? Aonde Eu disse isso? Você que não entendeu então!

O que disse é que um Objeto Valor pode conter referências a Entidades, não disse que esse objeto valor pode ser alterado, de maneira alguma!
Se pegarmos o proprio exemplo do Evans da Rota como um Objeto Valor e as Cidades como Entidades. Se os atributos das entidades mudarem a rota vai continuar sendo a mesma não vai? Digamos que rodovia tenha 3 pistas e passe a ter 6 a Rota irá mudar? Não né! Agora uma coisa diferente é eu permitir que, se eu “compartilhar” uma referencia desse objeto Rota com outro objeto, que esse objeto substitua alguma das instancias da rota, digamos, troque a cidade de São Francisco por Chigago, isso quebraria alguma invariante do meu objeto Rota tornando o inválido, por isso o Objeto Rota tem que ser Imutável.
Um Objeto Valor pode conter Entidades porque mesmo que os atributos das entidades variem, elas continuam sendo sempre a mesma entidade pois sua identidade não muda. Uma rodovia não passa a ser uma nova rodovia por que deixou de ter 3 pistas para ter 6, a identidade dela continua sendo a mesma! Assim eu não quebro Imutabilidade.

Já com Entidades com Objetos Valor é diferente. Digamos que eu tenha uma Entidade Pessoa e essa possui um Objeto Valor Endereco. Se eu tenho dois Objetos Pessoas que residem juntos eu posso fazer com que elas compartilhem a mesma referência para um Objeto Endereco. Só que se uma delas se mudar e alterar os atributos do objeto Endereco vai acabar modificando o endereço da outra pessoa também! Então tenho que tornar esse objeto Endereco Imutável, não permitindo que seus atributos sejam alterados quando o objeto for compartilhado. Então quem se mudasse teria que criar uma nova instancia do objeto Endereco para si!

[quote=Edufa] Não posso alterar diretamente C, mas alterando B, C é alterado.
um objeto para ser considerado imutável, tem de garantir que todos os objetos que ele referencia tb são?

Porém se B tiver o hashCode e equals, definidos usando-se apenas o codigo (que não é alterado) ele seria imutável ou mutável?
[/quote]
Por isso que gosto da engenharia, tu apreende a utilizar a palavra “Depende”!

Se eu compartilhar C e algum objeto alterar o objeto B e esse quebrar uma invariante de C (o nome e código são importantes para C) então eu não poderia permitir que B fosse alterado! Então eu teria que compartilhar uma cópia de B (ou torna-lo imutável):

...
public B getB() {return new B(b.codigo, codigo.nome); }  

Agora, se eu puder alterar B de forma que isso não quebre nenhuma invariante de C, ou seja se o nome puder ser alterado pois o que importa para C é somente o código então B não necessita ser imutável!

É por isso que um Objeto Valor pode conter referências para Entidades, mesmo que os atributos da entidade mudem ela continua sendo a mesma entidade por que sua identidade não muda!
Claro, e isso é óbvio, que se algum atributo da entidade for importante para o Objeto Valor de modo que, se for alterado, possa quebrar uma de suas invariantes, então não posso utilizar uma referência e terei que ter uma cópia dessa entidade. Também não posso permitir que essa cópia seja alterada se eu compartilhar uma referência do meu Objeto Valor!
Não sei se fui claro! Conseguiu entender?

Xandy,

[code]class Rota {

private Cidade origem;
private Cidade destino;

public Rota(final Cidade origem, final Cidade destino) {
this.origem = origem;
this.destino = destino;
}

public Distancia distancia() {
return origem.distanciaAte(destino);
}
}[/code]

Se o método distanciaAte depender de algum estado mutável de Cidade, é possível que ele retorne valores diferentes ao longo do tempo, porque Rota armazena uma referência para Cidade.

É importante garantir que seu objeto imutável não exponha um comportamento que depende de um estado mutável?

Se Rota armazenasse uma cópia de Cidade, isso não aconteceria.

[quote=esmiralha]Xandy,

[code]class Rota {

private Cidade origem;
private Cidade destino;

public Rota(final origem, final destino) {
this.origem = origem;
this.destino = destino;
}

public Distancia distancia() {
return origem.distanciaAte(destino);
}
}[/code]

Se o método distanciaAte depender de algum estado mutável de Cidade, é possível que ele retorne valores diferentes ao longo do tempo, porque Rota armazena uma referência para Cidade.

É importante garantir que seu objeto imutável não exponha um comportamento que depende de um estado mutável?

Se Rota armazenasse uma cópia de Cidade, isso não aconteceria.[/quote]

Sim. No tópico acima, que respondi para o Edufa, no último paragrafo eu falei sobre isso!

"Claro, e isso é óbvio, que se algum atributo da entidade for importante para o Objeto Valor de modo que, se for alterado, possa quebrar uma de suas invariantes, então não posso utilizar uma referência e terei que ter uma cópia dessa entidade. Também não posso permitir que essa cópia seja alterada se eu compartilhar uma referência do meu Objeto Valor! "

No caso estou considerando que a Rota não dependa de nenhum dos atributos das Entidades a não ser da identidade da propria entidade! :wink:

Sim. E além disso, se é importante a linguagem garantir isso, ou o programador. É claro que o programador é responsável pelo design mas acredito que a linguagem tem que tornar a tarefa mais fácil possível, e clojure é um passo nessa direção sendo a unica (somada com linguagens mais puras e academicas, como haskell) com um modelo voltado para separação entre entidades x objetos valor. Se não fica que nem Java… Onde ninguém sabe o que é um objeto imutável! :roll:

[quote=esmiralha]
Se Rota armazenasse uma cópia de Cidade, isso não aconteceria.[/quote]

Poderia explicar porque? se o estado continua mutável…

[quote=mochuara]

[quote=esmiralha]
Se Rota armazenasse uma cópia de Cidade, isso não aconteceria.[/quote]

Poderia explicar porque?[/quote]

Porque sendo uma cópia, o objeto mutável não pode ser alterado exceto de dentro da própria classe Rota e você pode garantir que isso não aconteça.

Isso não é verdade, como bem observou o esmiralha.

Isso não contradiz o quote de cima e vai de encontro ao que estou dizendo, usar o código como referencia e não o proprio objeto?

[quote=mochuara][quote=x@ndy]
Um Objeto Valor pode conter Entidades porque mesmo que os atributos das entidades variem, elas continuam sendo sempre a mesma entidade pois sua identidade não muda. Uma rodovia não passa a ser uma nova rodovia por que deixou de ter 3 pistas para ter 6, a identidade dela continua sendo a mesma! Assim eu não quebro Imutabilidade.
[/quote]

Isso não é verdade, como bem observou o esmiralha.
[/quote]

O que o colega esmiralha colocou é uma coisa que eu já tinha falado com edufa e vou colocar aqui de novo:
“Claro, e isso é óbvio, que se algum atributo da entidade for importante para o Objeto Valor de modo que, se for alterado, possa quebrar uma de suas invariantes, então não posso utilizar uma referência e terei que ter uma cópia dessa entidade. Também não posso permitir que essa cópia seja alterada se eu compartilhar uma referência do meu Objeto Valor!”

Não posso afirmar que o colega esmiralha tenha concordo, mas creio que sim, já que não questionou minha colocação.

[quote=mochuara][quote=x@ndy]

Isso não contradiz o quote de cima e vai de encontro ao que estou dizendo, usar o código como referencia e não o proprio objeto?[/quote][/quote]
Desculpe mas não entendi sua colocação. Pode explicar melhor?


Dando continuidade, me corrija se eu estiver enganado, mas o primeiro problema que eu vejo com seu ponto de vista é que você acredita que um OBJETO VALOR tem que ser obrigatoriamente imutável, o que está errado! O objeto valor tem que ser imutável apenas se for compartilhada uma referencia sua com outro objeto! Se eu não quiser, ou não puder torná-lo imutável e desejar compartilha-lo, posso fazer isso mediante uma cópia do mesmo! E se esse OBJETO VALOR não for compartilhado não é necessário sequer torná-lo imutável (não que isso não seja uma boa prática)

A segundo problema que vejo também é com o conceito de identidade e associação de objetos! Pelo que entendi até agora e com base na sua primeira colocação, no seu ponto de vista, o OBJETO VALOR é mutável quando possui uma referência para uma ENTIDADE pois os atributos desta podem mudar independentemente do OBJETO VALOR.
Com certeza os atributos da ENTIDADE podem mudar, mas isso não quer dizer que um OBJETO VALOR seja mutavel por causa disso. Se as invariantes do objeto valor dependerem apenas da identidade de uma ENTIDADE então ele pode ter uma referencia para a ENTIDADE sim, já que identidade da ENTIDADE nunca muda. Se eu necessitar compartilhar esse objeto valor, posso torna-lo imutável também, pois o que tenho que garantir é que nenhuma das suas invariantes seja quebrada e se as invariantes dependem apenas da identidade da minha ENTIDADE então o que devo fazer é não permitir que seja atribuído ao OBJETO VALOR uma referencia para uma outra ENTIDADE.

O que vejo é uma grande confusão com relação as invariantes de um objeto. Como disse antes, não é por uma rodovia recebe mais pistas mais que ela deixa de ser a mesma rodovia, muito menos uma rota vai ser alterada se essa rodovia receber mais pistas. Agora se a rota depende de algum atributo dessa rodovia, digamos de um acesso, então não devemos permitir que essa rodovia mude, pois se mudar vai quebrar uma invariante do meu objeto rota tornando o mesmo inválido. Como a rodovia é uma ENTIDADE para compartilha-la devemos então fornecer para a rota uma copia do objeto rodovia e não devemos permitir que os atributos dessa cópia sejam alterados.

Agora o que não entendo mesmo, é que você teima que estou errado mas não diz por que! Me diga aonde estou errando e com base no que?