É suficiente distinguir métodos apenas pelo nome do argumento (não pelo tipo) ou é melhor nomeá-lo mais explicitamente?
Por exemplo T Find<T>(int id)
vs T FindById<T>(int id)
.
Existe alguma boa razão para nomeá-lo de forma mais explícita (por exemplo, adicionar ById
) vs manter apenas o nome do argumento?
Uma razão pela qual consigo pensar é quando as assinaturas dos métodos são iguais, mas têm um significado diferente.
FindByFirstName(string name)
e FindByLastName(string name)
T Find<T>(string name)
ou(int size)
como planeja resolver os problemas inevitáveis?ID
objeto opaco e não apenas umint
. Dessa forma, obtenha uma verificação em tempo de compilação de que você não usa um ID para int ou vice-versa em alguma parte do seu código. E com isso você pode terfind(int value)
efind(ID id)
.Respostas:
Certamente, há uma boa razão para nomeá-lo mais explicitamente.
Não é principalmente a definição do método que deve ser auto-explicativa, mas o uso do método . E embora
findById(string id)
efind(string id)
sejam ambos auto-explicativos, há uma enorme diferença entrefindById("BOB")
efind("BOB")
. No primeiro caso, você sabe que o literal aleatório é, de fato, um ID. No último caso, você não tem certeza - pode realmente ser um nome ou algo completamente diferente.fonte
findById(id)
vsfind(id)
. Você pode ir de qualquer maneira nisso.double Divide(int numerator, int denominator)
a ser utilizado em um método:double murdersPerCapita = Divide(murderCount, citizenCount)
. Você não pode contar com os dois métodos com o mesmo nome da variável como há uma abundância de casos em que não é o caso (ou quando é o caso, é ruim de nomenclatura)Vantagens de FindById () .
Futuro à prova : Se você começar com
Find(int)
, e mais tarde tem que adicionar outros métodos (FindByName(string)
,FindByLegacyId(int)
,FindByCustomerId(int)
,FindByOrderId(int)
, etc), pessoas como eu tendem a gastar idades procurandoFindById(int)
. Não é realmente um problema se você puder e mudaráFind(int)
paraFindById(int)
quando necessário - a prova futura é sobre estes se s.Mais fácil de ler .
Find
está perfeitamente bem se a chamada parecerrecord = Find(customerId);
AindaFindById
é um pouco mais fácil de ler se estiverrecord = FindById(AFunction());
.Consistência . Você pode aplicar consistentemente o padrão
FindByX(int)
/ emFindByY(int)
qualquer lugar, masFind(int X)
/Find(int Y)
não é possível porque eles entram em conflito.Vantagens de Find ()
Find
é simples e direto e, ao ladooperator[]
dele, é um dos 2 nomes de funções mais esperados nesse contexto. (Algumas alternativas populares sendoget
,lookup
oufetch
, dependendo do contexto).FindById(int id)
, podemos remover facilmente a redundância alterando-a paraFind(int id)
, mas há uma troca - perdemos alguma clareza.Como alternativa, você pode obter as vantagens de ambos usando IDs fortemente tipados:
Implementação de
Id<>
: Digitando fortemente valores de ID em C #Os comentários aqui, bem como no link acima, levantaram várias preocupações sobre as
Id<Customer>
quais gostaria de abordar:CustomerId
eOrderID
são tipos diferentes (customerId1 = customerId2;
=> bom,customerId1 = orderId1;
=> ruim), mas sua implementação é quase idêntica, para que possamos implementá-los com copiar colar ou com metaprogramação. Embora exista valor em uma discussão sobre expor ou ocultar o genérico, a metaprogramação é para que servem os genéricos.DoSomething(int customerId, int orderId, int productId)
. Ids fortemente tipados também evitam outros problemas, incluindo o que o OP perguntou.int aVariable
. É fácil dizer que um ID está retidoId<Customer> aVariable
, e podemos até dizer que é um ID de cliente.String
é apenas um invólucrobyte[]
. O agrupamento ou encapsulamento não está em conflito com a digitação forte.operator==
eoperator!=
também, se você não quiser confiar exclusivamente emEquals
:.
fonte
Outra maneira de pensar sobre isso é usar o tipo de segurança da linguagem.
Você pode implementar um método como:
Onde FirstName é um objeto simples que envolve uma string que contém o primeiro nome e significa que não pode haver confusão quanto ao que o método está fazendo, nem nos argumentos com os quais é chamado.
fonte
string name = "Smith"; findById(name);
que é possível se você usar tipos gerais não descritos.DWORD
LPCSTR
clones etc. e pensa "é um int / string / etc.", chega ao ponto em que você passa mais tempo sustentando suas ferramentas do que realmente criando código .int
s são frequentemente somados, multiplicados etc., o que não faz sentido para IDs; então eu fariaID
diferenteint
. Isso pode simplificar uma API, restringindo o que podemos fazer com um valor (por exemplo, se tivermos umID
, ele só funcionará comfind
, não por exemplo,age
ouhighscore
). Por outro lado, se nos encontrarmos convertendo muito ou escrevendo a mesma função / método (por exemplofind
) para vários tipos, isso é um sinal de que nossas distinções são muito boas #Vou votar em declarações explícitas como FindByID .... O software deve ser criado para o Change. Deve estar aberto e fechado (SOLID). Portanto, a classe está aberta para adicionar um método de localização semelhante, como, por exemplo, FindByName ... etc.
Mas FindByID está fechado e sua implementação é testada em unidade.
Não vou sugerir métodos com predicados, eles são bons em nível genérico. E se, com base no campo (ByID), você concluir uma metodologia diferente.
fonte
Estou surpreso que ninguém tenha sugerido usar um predicado como o seguinte:
Com essa abordagem, você não apenas reduz a superfície da sua API, mas também dá mais controle ao usuário que a usa.
Se isso não for suficiente, você sempre poderá expandi-lo para suas necessidades.
fonte