Devo criar interfaces para objetos de transferência de dados?

15

É uma boa ideia ou uma má ideia criar uma interface para objetos de transferência de dados? Presumindo que o objeto seja geralmente mutável.

Embora meu exemplo seja em Java, ele deve ser aplicável a qualquer outra linguagem que tenha conceitos semelhantes.

interface DataTransferObject  {
    String getName();
    void setName(String name);
}

class RealDataTransferObject  implements DataTransferObject {

    String name;
    String getName() {
        return name;
    } 
    void setName(String name) {
        this.name = name;
    }
}

Claro, este é um exemplo simplificado, na vida real pode haver mais campos.

    
por Archimedes Trajano 02.02.2013 / 08:27
fonte

7 respostas

21

A resposta geral é no , porque você nunca deve adicionar código sem ter uma razão específica e concreta para isso, e não há uma razão geral para essa interface.

Dito isso, às vezes pode haver um bom motivo. Mas em todos os casos eu vi, essas interfaces eram parciais, cobrindo apenas uma ou algumas propriedades compartilhadas por várias classes que eu queria usar polimporficamente sem dar-lhes uma superclasse comum. Os candidatos típicos são uma propriedade Id para usar em algum tipo de registro ou uma propriedade Name para exibir ao usuário. Mas pode ser útil em qualquer caso em que você queira que algum código manipule tudo o que tem um X - basta criar uma interface XSource que contenha os métodos getX (e, somente se necessário, setX ).

Mas uma interface separada para cada classe de modelo, contendo todas as propriedades? Eu não posso imaginar uma boa razão para fazer isso. Uma razão ruim seria um framework mal projetado que requer isso; Os EJBs de entidades fizeram exatamente isso, se bem me lembro. Felizmente eles foram tão ruins que nunca ganharam muita tração e estão obsoletos desde o EJB 3.0

Sidenote: por favor, evite usar o termo "objeto de valor" para descrever Java beans com apenas getters e setters triviais - ele entra em conflito com a definição mais comum de value object como algo sem identidade que geralmente é imutável. Um termo melhor seria DTO ou classe de modelo - embora no último caso, note que os modelos de domínio anêmico são considerados antipadrões.

    
por 02.02.2013 / 11:08
fonte
2

As interfaces definem um contrato entre as classes que implementam as interfaces e seus clientes. Eles são usados como um mecanismo de abstração para que os clientes possam manipular "coisas que tenham determinado comportamento".

Portanto, a resposta geral à pergunta "devo criar e usar essa interface?" é: Sim, se você puder associar um (um único) conceito sendo semanticamente relevante para seus clientes.

Por exemplo, Comparable é uma boa interface, porque explica que as coisas podem ser comparadas graças a um dos seus métodos e, como cliente, estou interessado em lidar com objetos comparáveis (por exemplo, classificando - os). Um contrario, CoolStuff não é uma boa interface se você admitir que os objetos legais não têm um comportamento específico (na verdade, você pode imaginar um software em que lidar com objetos legais faz sentido, porque eles têm um comportamento comum, como um método beCool ).

No seu caso particular, acredito que sua interface é inútil. Quem vai usá-lo, como e quando? Você não pode criar uma interface para cada um dos valores mutáveis. Então pergunte a si mesmo qual é a propriedade relevante e interessante por trás de seus métodos.

Se o que você quer é lidar com objetos tendo todos os seus valores mutáveis acessíveis através de alguns métodos, dê uma olhada na noção de Java bean e na maneira como você pode forçar suas classes a adotar suas convenções.

    
por 02.02.2013 / 19:44
fonte
2

Como Michael disse, não adicione uma interface, a menos que você tenha uma necessidade específica para isso.

O teste é um bom exemplo. Embora eu prefira usar colaboradores reais, se eles forem apenas "objetos de valor", como você os chama, para isolamento de teste de unidade real, talvez seja necessário criar um objeto falso para teste. Nesse caso, uma interface é bastante útil.

    
por 02.02.2013 / 21:41
fonte
1

Se você quiser que este objeto tenha algum tipo de validação de campos no futuro, você deve incorporá-los nos estágios iniciais.

    
por 02.02.2013 / 08:32
fonte
1

A criação de interface está correta, mas NÃO é a maneira como seu exemplo funciona. Você deve remover o setter da interface, e tudo ficará bem:

interface ValueObject {
  String getName();
};

Isto permite muitas implementações diferentes, como o nome pode ser buscado no banco de dados ... O Setter deve estar em uma interface diferente.

    
por 02.02.2013 / 12:13
fonte
0

A 'interface para objeto de valor' é o que eu uso para chamar um acessador.

Eu experimentei políticas diferentes relacionadas aos acessadores. Algumas pessoas defendem quando, tanto quanto possível, outras proibem reduzir a quantidade de código a ser escrita.

Alguns rationnals para acessadores (ou uso direto de valor) são os seguintes:

  • Accessors permite alterar mais tarde a maneira como o valor é armazenado
  • Accessors permite adicionar log de acesso quando você deseja depurar seu software (ao adicionar uma chamada de log em um único método, você captura cada alteração de valor)
  • Os acessores estão mais de acordo com a programação de objetos, cada variável sendo encapsulada por métodos
  • Accessors reduzem a expressividade do código (mais SLOC para o mesmo resultado)
  • Accessors leva um pouco de CPU

Eu pessoalmente defendo reduzir o número de acessadores e usá-los quando você espera que o setter (setName) se torne mais do que uma simples afetação mais tarde.

    
por 02.02.2013 / 13:00
fonte
0

Esse tipo de objeto de valor é de nível muito baixo. Eu sugiro empurrá-lo em uma das duas direções: (1) tornar o objeto de valor imutável, ou seja, como um valor real , ou (2) elevar a mutabilidade para um domínio de nível superior orientado função de negócios, o que significa que devemos expor interfaces em termos de unidades relevantes de domínio de funcionalidade.

    
por 02.02.2013 / 17:22
fonte