O ID comercial conhecido de uma entidade deve ser representado com um tipo dedicado em DDD / OOP?

9

Em termos práticos, significa usar um costume (imutável) classsobre um stringou outro tipo primitivo.

Exemplos:

  1. Publicação: International Standard Book Number.
  2. Finanças: Número Internacional de Identificação dos Valores Mobiliários.

Vantagens:

  1. Pode garantir o formato de um identificador.
  2. Torna-se um membro de primeira classe do modelo.

Desvantagens:

  1. Adiciona atrito persistente (por exemplo, Entity Framework).
  2. Mais código.
Den
fonte
Você deve usar uma classe personalizada? Certo. Você deve usá-los como IDs? Absolutamente Não :) Um ID com significado comercial causaria problemas ao longo do caminho.
Songo
2
@Songo Para mim, é um argumento que os IDs devem ter semântica de valor , mas tipos primitivos não são os únicos com semântica de valor, de modo que isso não exclui necessariamente as classes imo. Sinta-se livre para postar uma resposta concorrente, desde que eu esqueci de fazer esse ponto.
Ixrec 21/08/2015
11
Uma velha pergunta minha abordou o assunto com opiniões diferentes: programmers.stackexchange.com/questions/281827/… Criei os tipos e continuo fazendo isso.
Ziv

Respostas:

6

Se você puder dar à classe funcionalidade útil suficiente para justificar a complexidade adicional de não ser uma sequência, faça-o. Para identificadores como ISBN e ISIN, suspeito que não seja esse o caso.

Para que uma classe de identificador seja útil, seria de esperar algo parecido com isto:

class ISIN {
    fromCUSIP()
    fromRawISINString()
    toString(ISIN::FormatType)
    getExchange()
    getCountryCode()
    getLastFourDigits()
    getWhateverCode()
    ...
}

Se, em vez disso, parecer mais com isso:

class ISIN {
    getString()
    setString()
}

Depois, abandonei a classe inteiramente, usei strings regulares em todos os lugares e certifique-se de usar consistentemente "isin" em todos os nomes de variáveis ​​relevantes.

Observe que, em alguns idiomas, a adição de um novo tipo quase não tem "complexidade adicionada" em programas típicos; nesse caso, você seria incentivado a criar o novo tipo, mesmo que ele não tivesse nenhuma funcionalidade. Mas esse não é o caso das linguagens OOP tradicionais, como o C ++.

Ixrec
fonte
6

Eu diria vamos lá. Eu argumentaria que as vantagens superam as desvantagens neste caso. É provável que o código extra seja mínimo e a questão da persistência possa ser resolvida com bastante facilidade, fornecendo algum tipo de conversor entre sua nova classe e o tipo que o banco de dados espera (nunca usei o Entity Framework, mas sei que isso é relativamente simples em Hibernate).

Uma das vantagens que você pode obter ao definir sua própria classe é que o compilador pode garantir que qualquer método que queira um ISBN ou um ISIN saiba em tempo de compilação se você tentar passar o valor errado. Também será muito mais difícil substituir acidentalmente esse campo na sua entidade. Podemos evitar erros comuns como este completamente:

book.setAuthor(otherBook.getAuthorName());
book.setIsbn(otherBook.getAuthorName());
book.setPrice(otherBook.getPrice())

Se o ISBN for uma classe e não um tipo primitivo, o código acima nem será compilado, economizando muito tempo de depuração posteriormente.

Matt Watson
fonte
11
setters e getters? É 1992?
Route de milhas 26/08/15