Uma boa regra geral é que os nomes dos métodos devem ser verbos ou predicados, de modo que o objeto no qual você os chama ( self
na convenção padrão do Python, this
na maioria das outras linguagens) se torne o assunto.
Por essa regra, file.close
é meio errado, a menos que você siga o modelo mental de que o arquivo se fecha ou que o file
objeto não representa o arquivo, mas um identificador de arquivo ou algum tipo de objeto proxy.
Um saco de pancadas nunca se perfura, portanto, punchingBag.punch()
está errado de qualquer maneira. be_punched()
é tecnicamente correto, mas feio. receive_punch()
pode funcionar ou handle_punch()
. Outra abordagem, bastante popular no JavaScript, é tratar chamadas de método como eventos, e a convenção deve incluir o nome do evento, prefixado com 'on', para que seja on_punched()
ou on_hit()
. Como alternativa, você pode adotar a convenção de que particípios passados indicam voz passiva e, por essa convenção, o nome do método seria justo punched()
.
Outro aspecto a considerar é se o saco de pancadas realmente sabe o que o atingiu: faz diferença se você o perfura, bate com um graveto ou se depara com um caminhão? Se sim, qual é a diferença? Você pode resumir a diferença em um argumento ou precisa de métodos diferentes para diferentes tipos de punição recebida? Um único método com um parâmetro genérico é provavelmente a solução mais elegante, porque mantém o grau de acoplamento baixo, e esse método não deve ser chamado punched()
ou handle_punch()
, mas algo mais genérico receive_hit()
. Com esse método, você pode implementar todos os tipos de atores que podem atingir os sacos de pancadas, sem alterar o próprio saco de pancadas.
Hitable
.Eu acho que é uma questão conceitual (como pensamos sobre o mundo). Tudo bem dizer:
door.close()
paper.fold()
file.close()
É estranho dizer:
bag.punch()
Precisaria ter algo para se socar em primeiro lugar (por exemplo, braços). Você provavelmente diria:
punching_bag.move()
Tudo bem para objetos programáticos fazerem coisas que normalmente outras pessoas fazem com / com eles (no "mundo real"). Mas acho que deve sempre fazer pelo menos algum sentido que a coisa esteja fazendo isso com ela mesma . Você deve poder imaginá-lo facilmente sem ficar obscuro (como no caso do
punching_bag
).fonte
É uma questão de gosto, eu acho.
Punching bag
Opunch()
método de é pelo menos consistente comfile.close()
ouframe.move()
no sentido de experimentar ação em si mesmo. Maior pergunta seria: porBoxer
que tempunch(something)
método?fonte
Coach.sayPunchToBoxer()
,Boxer.punchNearestBag()
eBag.punch()
. Caso contrário, você deve adivinhar o que acontecerá toda vez que ligarCoach.punch()
. A regra geral é: se o objeto que experimenta ação não for especificado no nome do método, o destinatário será esse objeto.Você tem duas mensagens diferentes: uma para comandar um objeto a ser perfurado e outra para informar um objeto que foi perfurado. Considere que um objeto Boxer provavelmente precisará responder a ambos . Diferentemente . Essa é realmente uma boa razão para dar nomes diferentes a eles.
Minha inclinação seria manter
punch(boxer, object, strength)
e renomear o método oposto apunched
. Você pode chamá-lohandle_punch
ou algo assim, mas ainda é ambíguo se é para manipular um comando de soco ou a notificação de que ele foi socado.fonte
defend
neste caso em particular). Mas o saco de pancadas nunca será bidirecional assim. E já existe este file.close () ...defend
é um comando. É uma ação possível que um objeto poderia executar em respostapunched
, mas você não gostaria que outros objetos invocassemdefend
diretamente.Sua abordagem acabará por levar a códigos muito acoplados.
Para resumir Eric Lippert idealmente aqui, você gostaria que o boxeador fosse capaz de perfurar muitas coisas. Ter o saco de pancadas como assinatura da função boxeador implica que o boxeador seja criado com um conhecimento imediato de Tudo (que é passível de punção). Além disso, dar um soco e receber um soco são duas coisas MUITO diferentes, portanto elas não devem compartilhar o mesmo nome.
Prefiro modelar isso como um Boxer que cria um soco (outro objeto que contém o atributo de força, alcance, direção, etc.).
Em seguida, faça com que o saco de pancadas com um método como o onPunch, que recebe esse objeto de punção, possa calcular o efeito do punção sobre si mesmo.
Tendo isso em mente, o nome das coisas importa muito. Ele deve se encaixar no modelo mental que você tem da situação. Se você está tentando explicar como algo pode acontecer que não faz sentido à primeira vista, ou se você está tendo mais dificuldade em nomear algo, talvez seu modelo esteja errado e precise mudar.
É difícil mudar um modelo depois que você começou, as pessoas geralmente tendem a distorcer a realidade para se ajustar ao modelo. O problema é que, ao dobrar as coisas para encaixar (como um saco de pancadas que pode perfurar as coisas), o mundo que você está criando se torna cada vez mais complexo e as interações ficam cada vez mais difíceis de implementar. Você chegará a um ponto em que adicionar até a coisa mais trivial se tornará um pesadelo de mudanças e bugs. Essa dívida técnica conceitual pode ter um preço muito alto, mesmo que o custo inicial tenha sido percebido na época como a coisa mais barata a se fazer.
fonte
Esse é o problema que chamo de confusão "objeto / sujeito" e é bastante prevalente.
As frases geralmente têm um sujeito que faz o verbo em seu objeto de destino .
Agora, com relação à programação, a única coisa que realmente faz as coisas é o computador. Ou virtualmente um processo, fio ou fibra. Os objetos não são animados por padrão. Eles não têm seus próprios threads em execução, então não podem realmente fazer nada.
Isso significa que os métodos operam neles, eles são o alvo da ação e não quem a executa. É por isso que os chamamos de "objetos" e não de "sujeitos"!
Quando você diz
File.close
que não é o arquivo que se fecha, é o thread em execução atual que fecha o arquivo. Se você disserArray.sort
, o segmento em execução atual classifica a matriz. Se você dizHttpServer.sendRequest
, o encadeamento em execução atual envia a solicitação ao servidor (não vice-versa!). Da mesma forma, dizerPunchingBag.punch
significa que o fio de corrida atual perfura a bolsa.Isso significa que, se você deseja
Boxer
perfurar, deve ser uma subclasse de umThread
para que possa executar ações como sacos de perfuração em sua função de rosca.No entanto, às vezes também faz sentido dizer que o saco de pancadas se perfura no caso em que cada objeto tem seu próprio encadeamento. Você pode evitar condições de corrida e implementar chamadas de método como passagem de mensagem: você perfura o saco enviando a
punch
mensagem, são perfurações no encadeamento ele envia apunch successful
mensagem de volta , mas isso é apenas um detalhe de implementação.fonte
Concordo que "punch" é um bom nome de método para a classe Boxer, pois (com alguns ajustes) poderia ser reutilizado contra outros objetos. Também descreve com precisão que um objeto de uma classe está executando uma ação em outro objeto. No entanto, renomearia o método para "doPunch", para demonstrar mais claramente a relação.
Para a classe PunchingBag, no entanto, acho o nome do método muito vago ou um pouco impreciso do que está acontecendo no método. Quando vejo "soco", acho que algo está socando outra coisa. No entanto, aqui, o objeto PunchingBag está reagindo a um soco de um objeto (nesse caso, um objeto Boxer). Portanto, renomeio o método aqui para "isPunched" para ilustrar que o objeto está reagindo a um soco.
Porém, esta é a minha interpretação de como eu nomearia os métodos. É tudo uma questão de gosto e quais padrões você está seguindo.
fonte
isPunched
é realmente enganoso (mais ou menos, dependendo do esquema de nomenclatura da estrutura).punch()
?hmmmm. Estou questionando o saco de pancadas como uma classe, porque você realmente não se importa com o saco de pancadas - você se preocupa com o impacto e a força do punho dos Boxers. portanto, os métodos devem ser sobre o que quer que esteja medindo e relatando o impacto do soco. mesmo que isso venha do 'saco de pancadas', a nomeação ainda deve revelar a responsabilidade - como punchImpactMeter etc.
fonte
O boxeador soca o saco de pancadas -> boxer.punch
O punchingbag é perfurado pelo boxeador -> punchingbag.get_punch
fonte