Os nomes das interfaces devem começar com um prefixo “I”?

67

Eu tenho lido " Código Limpo " por Robert Martin para se tornar um programador melhor. Embora nada disso tenha sido realmente inovador, isso me fez pensar de maneira diferente sobre a maneira como eu desenho aplicativos e escrevo código.

Há uma parte do livro com a qual eu não apenas não concordo, mas também não faz sentido para mim, especificamente no que diz respeito às convenções de nomenclatura de interface. Aqui está o texto, tirado diretamente do livro. Eu tenho ousado o aspecto disso eu acho confuso e gostaria de esclarecimento.

I prefer to leave interfaces unadorned. The preceding I, so common in today’s legacy wads, is a distraction at best and too much information at worst. I don’t want my users knowing that I’m handing them an interface.

Talvez seja porque sou apenas um estudante, ou talvez porque nunca fiz programação profissional ou em equipe, mas gostaria que o usuário soubesse que é uma interface. Há uma grande diferença entre implementar uma interface e estender uma classe.

Então, minha pergunta se resume a: "Por que devemos esconder o fato de que alguma parte do código está esperando uma interface?"

Editar

Em resposta a uma resposta:

If your type is an interface or a class is your business, not the business of someone using your code. So you shouldn't leak details of your code in this thrid party code.

Por que não devo "vazar" os detalhes de se um determinado tipo é uma interface ou uma classe para um código de terceiros? Não é importante para o desenvolvedor de terceiros usar meu código para saber se eles estarão implementando uma interface ou estendendo uma classe? As diferenças não são tão importantes quanto as estou fazendo para estarem na minha cabeça?

    
por Charles Sprayberry 01.11.2011 / 22:50
fonte

7 respostas

64

Se você parar para pensar sobre isso, verá que uma interface não é semanticamente muito diferente de uma classe abstrata:

  • Ambos possuem métodos e / ou propriedades (comportamento);
  • Nenhum dos campos deve ser privado (dados);
  • Nenhum dos dois pode ser instanciado diretamente;
  • Derivar de um significa implementar quaisquer métodos abstratos que ele tenha, a menos que o tipo derivado também seja abstrato.

Na verdade, as distinções mais importantes entre classes e interfaces são:

  • As interfaces não podem ter dados privados;
  • Os membros da interface não podem ter modificadores de acesso (todos os membros são "públicos");
  • Uma classe pode implementar várias interfaces (em oposição a geralmente poder herdar de apenas uma classe base).

Como as únicas distinções particularmente significativas entre classes e interfaces giram em torno de (a) dados privados e (b) tipo hierarquia - nenhum dos quais faz a menor diferença para um chamador - geralmente não é necessário saber se um tipo é uma interface ou uma classe. Você certamente não precisa da indicação visual .

No entanto, existem alguns casos importantes em que você deve estar ciente. Em particular, se você estiver usando reflexão, interceptação, proxies dinâmicos / mixins, tecelagem de bytecode, geração de código ou qualquer coisa que envolva o messing diretamente com o sistema de digitação do ambiente ou o próprio código - então é muito útil e às vezes é necessário saber logo de cara se você está lidando com uma interface ou uma classe. Você claramente não quer que seu código falhe misteriosamente porque você tentou adicionar uma classe, em vez de uma interface, como um mixin.

No entanto, para um código de lógica de negócios típico, típico, de baunilha, as distinções entre as classes abstratas e as interfaces não precisam ser anunciadas, porque nunca entrarão em ação.

Dito isto, prefiro prefixo minhas interfaces C # com I , porque essa é a convenção .NET usada e defendida pela Microsoft. E quando estou explicando as convenções de codificação para um novo desenvolvedor, é muito menos complicado usar as regras da Microsoft do que explicar por que temos nossas próprias regras "especiais".

    
por 02.11.2011 / 02:20
fonte
13

De muitas maneiras, a consistência é mais importante do que a convenção. Contanto que você seja consistente em seus esquemas de nomenclatura, eles não serão difíceis de se trabalhar. Prefixo interfaces com um eu se você gosta, ou apenas deixa o nome sem adornos, não importa para mim desde que você escolha um estilo e fique com ele!

    
por 02.11.2011 / 15:13
fonte
11

O livro está cheio de coisas boas, mas eu ainda adicionaria "I" ao nome da interface.

Imagine que você tem public interface ILog com uma implementação padrão public class Log .

Agora, se você decidir ter public interface Log , de repente você precisará alterar a classe de registro para public class LogDefault ou algo nessas linhas. Você passou de ter um personagem extra para sete - certamente isso é um desperdício.

Existe frequentemente uma linha tênue entre teoria e prática. Em teoria, esta é uma boa ideia, mas na prática não é tão boa.

    
por 08.04.2014 / 11:55
fonte
8

Bem, não se trata de implementar a interface ou estender uma classe. Nestes casos, você sabe de qualquer maneira o que está fazendo.

No entanto, quando o código de terceiros (outro módulo do aplicativo, por exemplo) manipula seus dados, esse código não deve se importar se você estiver apresentando uma interface ou uma classe.

Este é todo o ponto de abstração. Você está apresentando a esse código de terceiros um objeto de um determinado tipo. Este tipo dado tem alguma função de membro que você pode chamar. Isso é o suficiente.

Se o seu tipo é uma interface ou uma turma, é o seu negócio, não o negócio de alguém que usa o seu código. Então você não deve vazar detalhes do seu código para este código de terceiros.

A propósito, interfaces e classes são tipos de referência no final. E isso é o que importa. Então, isso é o que sua convenção de nomenclatura deve enfatizar.

    
por 01.11.2011 / 22:58
fonte
5

A maioria das respostas parece assumir que a linguagem de programação é Java ou C #, onde existe um conceito (ou palavra-chave) para interfaces / classes abstratas. Nesses casos, em um IDE decente, é imediatamente visível com qual tipo de classe se lida, e escrever public interface IMyClass é duplicação desnecessária. É como se você não fosse escrever public final FinalMyClass - imagine colocar todas as palavras-chave no nome das classes.

No entanto, na minha opinião em C ++, a situação é um pouco diferente, pois é preciso mergulhar no arquivo de cabeçalho e ver se a classe tem algum método virtual para descobrir se é uma classe abstrata. Nesse caso, posso ver claramente um argumento para escrever class AbstractMyClass .

Então minha resposta seria: Depende da linguagem de programação.

2 anos de experiência em C ++ mais tarde Eu provavelmente consideraria uma prática ruim prefixar nomes de classes com Abstract , embora eu diria que existem provavelmente bases de código tão complexas que isso pode fazer sentido.

    
por 08.04.2014 / 11:49
fonte
3

Siga os idiomas do idioma que você está usando.

Cada idioma tem suas próprias expressões idiomáticas e diretrizes de codificação. Por exemplo, em C #, é idiomático prefixar interfaces com I. Em Go, não é.

    
por 29.02.2016 / 11:03
fonte
0

No meu código (Java), tenho a tendência de ter essa convenção nas APIs que exponho aos chamadores:

  • A funcionalidade é fornecida por meio de interfaces e nunca por classes.
  • Partes não funcionais são classes.

Por não funcional, quero dizer coisas como estruturas de dados puros (como classes que atuam como pontes para serialização XML ou o ORM), enumerações e exceções, as quais não podem ser interfaces (bem, você pode para as classes de dados puros, mas é muito trabalhoso para muito pouco ganho já que não há nada que essas classes façam exceto armazenar dados).

Em termos de convenções de nomenclatura, as interfaces tendem a mapear nomes de agentes (por exemplo, FooBarWatcher ) ou adjetivos (por exemplo, FooBarWatchable ) e mapear classes de dados puros e enumerações a substantivos não ativos (por exemplo,% código%); o IDE pode orientar o consumidor da API sem convenções de nomenclatura especiais. As exceções seguem as convenções comuns do Java ( FooBarStatus , FooBarException , FooBarError ), é claro.

Eu também coloco as interfaces em seu próprio pacote ou mesmo em sua própria biblioteca, apenas para garantir que não seja tentado a quebrar minhas próprias regras. (Isso também me ajuda a gerenciar a compilação quando estou derivando o código de fontes externas, como documentos WSDL.)

    
por 02.11.2011 / 12:42
fonte