[Nota: O abaixo é um pouco pesado em C # em sua sintaxe e convenções, como citar regras FxCop, porque esse é o meu histórico, mas o objetivo desta discussão é ser independente de idioma e os exemplos de código usados geralmente devem ser considerados como pseudo-código. - Mike]
Acho que todos concordamos que as classes geralmente devem ser projetadas para que suas instâncias de objetos sejam imutáveis sempre que possível, e os resultados de chamar membros da classe devem estar livres de efeitos colaterais, tanto quanto possível.
As convenções de nomenclatura histórica, no entanto, tendem a usar a voz ativa: 'GetSomething', 'DoSomehing' etc. etc., e isso é bom porque indica claramente que ação o aluno deve executar.
Agora estou começando a pensar, no entanto, que os membros às vezes (ou possivelmente com freqüência) se beneficiam sendo nomeados no pretérito para conotar que um valor é retornado sem afetar o objeto referenciado.
Por exemplo, para um método que transpõe uma matriz, os estilos de nomenclatura atuais provavelmente o chamariam 'Array.Transpose', mas se esse membro retornar uma nova matriz, sem transpor o objeto referenciado, acho que chamando de 'Array.Transposed 'seria mais preciso e tornaria mais claro para o programador.
Ao trabalhar com um método 'Array.Transpose ()', pode-se tentar acidentalmente usar código como o seguinte:
Array myArray = new Array();
myArray.Transpose();
Mas se o método 'Transpose' retornar uma nova matriz sem afetar o objeto referenciado, esse código não fará nada - ou seja, 'myArray' silenciosamente não seria transposto. (Suponho que, se 'Transpose' fosse uma propriedade, o compilador perceberia que o acima não é legal, mas as diretrizes da FxCop determinam que um membro que realiza uma conversão deve ser um método.)
Mas se o método fosse nomeado no passado como 'Array.Transposed', seria mais claro para o usuário que a seguinte sintaxe é necessária:
Array myArray = new Array();
Array transposedArray = myArray.Transposed();
Outros nomes que eu acho que se encaixariam nessa categoria seriam os membros denominados 'Redimensionado' vs. 'Redimensionar', 'Deslocado' vs. 'Deslocamento' etc. O tempo presente seria usado para membros que afetassem o objeto referenciado, enquanto o o pretérito seria usado para membros que retornassem um novo valor sem afetar o objeto referenciado.
Outra abordagem que é mais comum atualmente é prefixar cada nome com "Get" ou "To", mas acho que isso adiciona peso desnecessário, enquanto a alteração no pretérito comunica o significado de maneira eficaz.
Isso faz sentido para outros programadores aqui, ou essa ideia de pretérito soa estranho demais ao lê-la?
Editar:
Ótimas discussões abaixo, agradeço muito a todos. Gostaria de resumir alguns pontos com base nos seus comentários e no meu próprio pensamento revisado a seguir.
Método de encadeamento de sintaxes "fluentes"
Com base nas discussões abaixo, o uso do tempo passado é provavelmente de algum valor quando usado em uma classe mutável, a fim de deixar claro quais membros afetam, ou não, o estado interno do objeto referenciado.
No entanto, para classes imutáveis, que deveriam ser a maioria dos casos (seria de esperar), acho que o uso do tempo passado pode tornar a sintaxe desnecessariamente estranha.
Por exemplo, com "sintaxes fluentes", como as criadas pelo encadeamento de métodos, o uso do tempo passado tornaria o código menos legível. Por exemplo, ao usar o LINQ via C #, uma cadeia de métodos típica pode ter a seguinte aparência:
dataSource.Sort().Take(10).Select(x => x.ToString);
Se alterado para o passado, isso se tornaria estranho:
dataSource.Sorted().Taken(10).Selected(x => x.ToString);
Lembre-se de que dataSource.Sorted () tem um significado mais claro do que dataSource.Sort (), porque as expressões LINQ sempre criam uma nova enumeração sem afetar a fonte. No entanto, como estamos plenamente conscientes disso ao usar esse paradigma, o uso do tempo passado é redundante e torna a "fluência" de lê-lo desajeitada, sem ganho real.
Uso de propriedades vs. métodos
Um problema importante abordado abaixo diz respeito às diretrizes do FxCop para o uso dos métodos "Get" versus propriedades somente leitura. Por exemplo, regra FxCop CA1024 .
Embora não mencionado explicitamente nessa regra do FxCop, o uso dos métodos "To" também parece se aplicar a esse raciocínio, pois os métodos ToXXXXXX () são métodos de conversão. E no caso de ToArray (), o método é um método de conversão e é um método que retorna uma matriz.
Uso do pretérito para propriedades booleanas
Alguns sugeriram que o tempo passado pode conotar um valor booleano, por exemplo, uma propriedade 'Succeeded' ou 'Connected'. Acredito que as réplicas abaixo enfatizando o uso de um 'É', 'Tem' ou 'É' para propriedades e campos booleanos estão corretas. O pretérito também pode ajudar nesse sentido, mas não tanto quanto usar o prefixo 'É'. Sinta-se à vontade para usar o tempo passado para propriedades e campos booleanos, isso ajuda, mas acho que é ainda mais importante prefixar o nome com 'Is', 'Has' ou 'Are'.
Conclusões Gerais?
Para a questão de Tranpose () vs. Transposed (), acho que 'skizzy' acertou, sugerindo que deveria ser Transpose () para uma ação mutante vs. GetTransposed () para um resultado não mutante. Isso torna 100% claro. Mas, novamente, acho que isso pode se aplicar apenas a uma classe mutável, como uma matriz.
Para classes imutáveis, especialmente onde uma sintaxe fluente de encadeamento de métodos pode ser usada, acho que essa sintaxe se tornaria desnecessariamente estranha. Por exemplo, compare:
var v = myObject.Transpose().Resize(3,5).Shift(2);
para:
var v = myObject.GetTransposed().GetResized(3,5).GetShifted(2);
Hmmm ... na verdade, mesmo aqui parece deixar 100% claro que o resultado não afeta a fonte, mas não tenho certeza.
Eu acho que para um paradigma como o LINQ, onde é bem conhecido, o uso de "Get" e / ou o tempo passado não é necessário, mas para uma nova API, ela pode ter algum valor - a princípio! Se a API contiver apenas objetos imutáveis, uma vez que o usuário entenda isso, o uso de "Get" e / ou o tempo passado apenas reduzirão a legibilidade.
Então, acho que não há respostas fáceis aqui. Acho que é preciso pensar em toda a sua API e escolher com cuidado!
-- Mike
Respostas:
O tempo passado parece meio estranho. Eu acho que você pretendia que a palavra fosse um adjetivo.
Aqui está minha sugestão para o problema que você pediu: em vez de
Transpose()
chamá-loGetTransposed()
. Dessa forma, você sabe que está recebendo algo e não está modificando o objeto.fonte
Transpose()
ainda pode ser interpretado como o ajuste do objeto especificado. Talvez isso deva ser uma construção da linguagem. :)object.Transpose()
vsobject:Transpose()
.AsTransposed
do queGetTransposed
nos casos em que chamadas repetidas consecutivas, sem efeitos colaterais, produzem resultados semanticamente idênticos (que podem ou não ser o mesmo objeto, mas não podem ser mostrados como objetos diferentes sem usar coisas comoReferenceEquals
ou equivalente) .Isso realmente faz sentido.
O que você está falando, na minha opinião, deve ser tomado como regra geral ao projetar uma API ou uma biblioteca. Somente então ele ofereceria um benefício tangível se o sistema for consistente em todas as classes.
Outra questão é que, em muitos casos, os usuários das interfaces não se importam com a maneira como o resultado é alcançado.
Transpose () transporá o objeto atual? Transpose () criará uma nova instância transposta e retornará a referência a ela? Ou talvez transponha uma vez, armazene em cache os resultados em uma cópia e retorne-a nas chamadas subseqüentes sem afetar o objeto atual?
Os usuários geralmente querem apenas obter o resultado transposto, e é por isso que muitos não se importam com a convenção de nomenclatura que você está propondo.
Mas, por si só, é uma proposta válida.
fonte
Eu discordo fortemente. O tempo passado é estranho e não é comumente usado (o que já é razão suficiente para não preferir).
Se o método modificou o objeto em que foi chamado, ele não deve retornar sozinho - isso deixa claro que modifica o objeto.
Da mesma forma, se o método não modificar o objeto em que foi chamado e construir um novo objeto, o método retornará um objeto do mesmo tipo. Esta é uma convenção clara e já comum.
A assinatura do método é, na minha opinião, uma convenção mais clara e muito mais usada para indicar se o método retorna um novo objeto ou modifica o chamado.
fonte
Parece razoável e existem precedentes - o Python possui ambos
list.sort()
esorted(seq)
. O primeiro é um método, o outro é uma função que atua em qualquer iterável e retorna uma lista.fonte
Na biblioteca de coleções Scala, existem alguns métodos no passado:
grouped
retorna um iterador que itera sobre os elementos de uma sequência em partes den
elementossorted
retorna uma versão classificada da coleçãoupdated
retorna uma nova versão da coleção com um elemento alteradoNo entanto, não tenho certeza se essa foi uma decisão consciente ou se eles simplesmente ficaram sem nomes, porque a biblioteca de coleções do Scala é muito rica. Por exemplo, há também
groupBy
esortBy
métodos, e oupdate
método é especial, porque o compilador reescreve atribuiçãopara dentro
Versões mais antigas do Scala de fato fez uso
update
para coleções imutáveis, mas terupdate
retorno uma nova versão em vez de mutação é muito estranho, porque obviamente você tem que atribuir o valor de retorno para alguma coisa, então por exemplo, "atualizar" uma entrada em um mapa imutável seria algo gostarAgora é
Em uma linguagem com um bom sistema de tipos, os tipos geralmente informam se a rotina muda ou não seus argumentos. Em Haskell, por exemplo, o tipo da versão imutável seria algo como
enquanto uma versão mutável seria como
fonte
Quando vejo um método / propriedade no tempo passado, imediatamente presumo que ele retorne um valor booleano. Sua proposta pode fazer sentido logicamente, mas parece estranha e estranha. Se eu tiver que explicar a alguém por que faz sentido, provavelmente não é uma boa convenção.
fonte
Eu não sou um grande fã de nomes de variáveis no tempo passado para imutabilidade - é uma convenção um tanto incomum e acho que causaria confusão, especialmente para aqueles indivíduos que não são particularmente fortes na gramática inglesa (e estou apenas brincando) há...)
Além disso, essas convenções eliminam a oportunidade de usar o pretérito para denotar outra coisa que eu acho mais importante: uma descrição do estado do objeto descrito, por exemplo, "itens processados" informa claramente que os itens de uma coleção já foram processado, que é uma informação lógica importante a ser transmitida.
Uma ideia melhor: tornar tudo imutável . Então você não precisa de nenhuma distinção lingüística sofisticada. Você sabe que você quer :-)
fonte