Nomeação da interface: prefixo 'Can-' vs sufixo '-Able'


29

É comum usar '-able' como sufixo para interfaces, por exemplo

Rotável Shootable potável enumerável imprimível serializável

Eu estava pensando que 'Can-' poderia melhorar porque pode ser mais descritivo. Sim, é mais prolixo e adiciona ruído ao nome da interface. Em particular, verbos passivos podem ser usados.

Por exemplo, 1 Shootable significa que o objeto é capaz de disparar (uma arma pode implementar isso) ou significa que pode ser atingido (uma placa de alvo pode implementar isso). Com o prefixo 'Can-', o primeiro seria "CanShoot" e o último seria "CanBeShotAt" ou "CanShootAt".

Por exemplo 2 Um documento 'CanBePrinted' e uma impressora 'CanPrint'

Ou devemos ficar com '-Able' e deixar a documentação fornecer o contexto?

Qualquer opinião.


Cara, use "-able". Período.
Tulains Córdova

2
Use ambos paraclass Cannibal implements Can, Able {}
Thomas Eding 18/07/2013

Respostas:


18

Talvez você queira o Is-capaz?

Alguns exemplos de .Net:

NetworkStream.Readable
NetworkStream.Writable
Stream.CanRead
Stream.CanWrite
Type.IsSerializable

Não parece haver um padrão uniforme. Vá com o que lê bem.

if (document.IsPrintable && printer.CanPrint) { printer.Print(document) }

Edição: Como apontado, a pergunta era sobre interfaces, não propriedades.

Nesse caso, não consigo encontrar nenhuma interface chamada Can-. As interfaces tendem a sempre usar -able. Eu concordo com esta terminologia. Um método pode solicitar como parâmetro a ISerializable objectou IPrintable document. Pedir um ICanBeSerialized objectou um ICanBePrinted documenté muito estranho de ler.

Por outro lado, a impressora, sugiro simplesmente chamar a interface IPrinter. Seu método estará pedindo um IPrinter device.

Leia a assinatura do método abaixo em voz alta. (Pessoalmente, considero o prefixo "I" silencioso.) Ele lê bem? Isso soa certo?

void PrintDocument(IPrinter device, IPrintable document)
{
    device.Print(document)
}

2
Document.IsPrintable é melhor que Document.CanBePrinted. Tanto quanto posso dizer, eles usavam -able para evitar a voz passiva.
Thanos Papathanasiou

"Pode ser impresso" parece um inglês mais adequado do que "é imprimível".
precisa saber é o seguinte

1
"A voz passiva é usada quando o foco está na ação. Porém, não é importante ou não se sabe quem ou o que está executando a ação." Só posso supor que eles queriam que o foco permanecesse no objeto e não na ação. Portanto, se um "Type.IsSerializable" lança uma exceção, a culpa é do Type. não os métodos ', mas se um "Type.CanBeSerialized" lançar uma exceção, você culparia o método e não o tipo. É certo que a diferença é pequena, mas está lá.
Thanos Papathanasiou

3
Vejo que esta é a resposta aceita, mas isso não responde à pergunta do OP. Os exemplos fornecidos são nomes de propriedades . O OP está pedindo uma convenção de nomenclatura para interface nomes, tais como ISerializable, IDataErrorInfo, e INotifyPropertyChanged.
22612 Kevin McCormick

@KevinMcCormick, bom ponto! Edita acima.
Mão-E-Comida

23

Gramaticalmente, "canFoobar" é um predicado, enquanto "Foobarable" é um adjetivo ou um substantivo (geralmente um substantivo no contexto de uma API).

Observe também a diferença sutil: -able implica um papel passivo no substantivo ao qual é aplicado, ou seja, se Algo for Foobarable, ele poderá ser foobarred por outra coisa; pode implicar um papel ativo, isto é, se Algo puderFoobar, ele poderá foobar em outra coisa. Ou, de um ângulo diferente: se A puder foobar B, então A.canFoobar()e B is Foobarable.

Em termos de expressividade OOP, eu associaria predicados a métodos ou propriedades, enquanto substantivos são classes ou interfaces. Tão:

instance.canFoobar();

class Something implements Foobarable { ... }

7

Pessoalmente, eu continuaria com a versão -able. Aqui está o meu motivo: a maioria dos editores gráficos (todos?) Sugere identificadores com base no que você digitou. Embora alguns deles sejam 'inteligentes' o suficiente para também pesquisar nos identificadores, alguns ainda oferecem apenas o início da pesquisa dos identificadores.

Para acelerar a digitação, reduza a lista de identificadores sugeridos com o menor número possível de pressionamentos de tecla. Quanto mais identificadores tiverem o mesmo começo, por exemplo, 'ICan-', mais caracteres você precisará digitar.

Se você acha que isso não é um problema no seu caso, isso é ótimo e eu recomendaria o uso de outros critérios para escolher uma convenção de nomenclatura. Em alguns casos, por exemplo, em nossa equipe, preferimos identificadores que distinguem após o menor número de pressionamentos de tecla possível.

Além disso, eu recomendaria usar a convenção de nomenclatura que torna seu código mais compreensível para os que trabalham no projeto. Converse com sua equipe. Não existe certo ou errado como tal. Apenas convenções que funcionam e convenções que funcionam menos.

Não esqueça que boas ferramentas de refatoração permitem renomear as coisas quantas vezes você quiser. Portanto, é fácil experimentar diferentes abordagens.


1
+1. Meu raciocínio seria o mesmo, coloque o verbo de controle primeiro para facilitar a pesquisa / localização / classificação no IDE.
pap

1
o intellisense não apenas funciona dessa maneira, mas também o texto de uma varredura humana, os prefixos tornam seu código menos legível
jk.

7

Claramente, o prefixo e o sufixo são opções quase óbvias para diferentes tipos de ações ou melhor, diferentes direções de uma ação.

O uso e as preferências atuais podem ser inconsistentes devido a várias razões.

Ação é executada por objeto:
CanShoot -> It brotos (at) algo
CanFly -> Ele voa
CanChange -> Ele muda

A ação é executada no objeto:
Legível -> Você pode lê-lo
Gravável -> Você pode escrever (para)
Imprimível -> Você pode imprimi-lo

Embora possa não ser uma regra ou mesmo necessariamente lógica, ajuda a adotar a convenção e manter a consistência do uso na nomeação de variáveis.


4

Eu acho que você pode querer distinguir entre capacidade e permissão. Enquanto Serializablee CanSerializeimplica que algo é capaz de ser serializado, também há problemas de permissão (ou talvez a falta de espaço em disco) e você pode precisar de considerar MaySerialize. Deixar as coisas em ~ableremove a necessidade de distinguir entre cane may.


SerializableIfNotDiskFullAndIfNotPermissionMissing ... Lol :)
Max

2

Ao subclassificar / implementar interfaces, acho que a regra é que você possa dizer "B é um A" (onde B implementa A). Não parece certo dizer:

A Documenté umCanBePrinted

Mas parece certo (ou pelo menos melhor) dizer:

A Documenté umPrintable


2

Eu acho que o Xable em termos de gramática e de convenções é melhor para nomes de interfaces, enquanto IsX, CanX, DoesX são melhores para nomes de propriedades.

Do MSDN:

"Nomeie propriedades booleanas com uma frase afirmativa (CanSeek em vez de CantSeek). Opcionalmente, você também pode prefixar as propriedades booleanas com Is, Can ou Has, mas apenas onde agregar valor." http://msdn.microsoft.com/en-us/library/ms229012.aspx


+1 para o link útil; Eu nunca pode descobrir o que as coisas de nomes
CamelBlues

0

Na minha opinião, a variante "-able" é muito mais legível do que a proposta "CanDoSomething", que impõe muito mais camelôs.


1
e Can- é mais um nome de método
catraca aberração

Nome da propriedade - consulte MSDN. Os nomes de métodos devem ser "verbos ou frases verbais". Além disso, o que há de errado com vários carrinhos?
Danny Varod

0

No Scala, *Ableé usado para interfaces, mas Can*é usado para o padrão de classe de tipo. Essencialmente, para poder chamar determinados métodos, um valor implícito de um determinado tipo deve existir no escopo. Às vezes, o nome desse tipo é prefixado Can.


Can * não é um bom nome para uma classe. Citação do MSDN: "as aulas nome, interfaces e tipos de valores com substantivos, sintagmas nominais, ou ocasionalmente frases adjetivo, usando caixa Pascal", link: msdn.microsoft.com/en-us/library/ms229040.aspx bom nome para classe seria Document, o nome aceitável seria Printable.
Danny Varod

Um exemplo no idioma Scala é o CanBuildFrom. Esta seria uma frase adjetiva. O caso de uso dessa classe é muito diferente do de outras classes. Instâncias dessa classe quase nunca são construídas nem resolvidas pelo cliente - elas estão disponíveis no escopo para certos tipos. Se eles estiverem disponíveis para um determinado tipo, os métodos que envolvem esse tipo, marcados para exigir essa classe, podem ser chamados. Isso existe para oferecer um mecanismo de extensibilidade mais flexível que a subtipagem. Veja scala-lang.org/node/114 .
precisa saber é o seguinte

Só me lembro de usar frases adjetivas para classes simuladas que implementam interfaces para testes de unidade - já que elas não tinham um papel real.
Danny Varod
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.