Хорошее практическое правило заключается в том, что имена методов должны быть глаголами или предикатами так, чтобы объект, к которому вы их вызывали ( self
в стандартном соглашении Python, this
в большинстве других языков), становился субъектом.
Это правило file.close
является своего рода неправильным, если вы не используете ментальную модель, согласно которой файл закрывается сам или file
объект не представляет сам файл, а скорее дескриптор файла или какой-либо прокси-объект.
Боксерская груша никогда не пробивает себя сама, поэтому punchingBag.punch()
в любом случае это неправильно. be_punched()
технически правильно, но безобразно. receive_punch()
может сработать или handle_punch()
. Другой подход, довольно популярный в JavaScript, состоит в том, чтобы рассматривать такие вызовы методов как события, и существует соглашение, заключающееся в том, чтобы использовать имя события с префиксом «on», так что это будет on_punched()
или on_hit()
. В качестве альтернативы вы могли бы принять соглашение, согласно которому причастия прошлых лет указывают на пассивный голос, и согласно этому соглашению имя метода будет справедливым punched()
.
Еще один аспект, который следует рассмотреть, заключается в том, знает ли боксерская груша, что на нее попало: имеет ли значение, бьете ли вы ее, бьете ее палкой или врезаетесь в нее грузовиком? Если так, то в чем разница? Можете ли вы свести разницу к аргументу или вам нужны разные методы для разных видов наказания? Один метод с универсальным параметром, вероятно, является наиболее элегантным решением, поскольку он поддерживает низкую степень связи, и такой метод не следует вызывать punched()
или handle_punch()
, а скорее как нечто более общее receive_hit()
. Используя такой метод, вы можете реализовать все виды актеров, которые могут поразить боксерские груши, не меняя саму боксерскую грушу.
Hitable
.Я думаю, что это концептуальная проблема (как мы думаем о мире). Можно сказать:
door.close()
paper.fold()
file.close()
Странно говорить:
bag.punch()
Во-первых, ему нужно было бы что-то ударить (например, оружие). Вы, вероятно, сказали бы:
punching_bag.move()
Программные объекты могут делать то, что обычно делают с ними / с ними (в «реальном мире»). Но я думаю, что всегда должно быть хоть какое-то чувство, что вещь делает это с собой . Вы должны быть в состоянии представить это легко, не становясь неясным (как в случае с
punching_bag
).источник
Это вопрос вкуса, я думаю.
Punching bag
Этотpunch()
метод, по крайней мере, соответствуетfile.close()
илиframe.move()
в смысле ощущения воздействия на себя. Большой вопрос был бы, почемуBoxer
естьpunch(something)
метод вообще?источник
Coach.sayPunchToBoxer()
,Boxer.punchNearestBag()
иBag.punch()
. В противном случае вы должны угадать, что будет происходить каждый раз, когда вы звонитеCoach.punch()
. Общее правило: если объект, который испытывает действие, не указан в имени метода, тогда получатель является этим объектом.У вас есть два разных сообщения: одно, чтобы дать команду объекту пробить, а другое сообщить объекту, что он был пробит. Учтите, что объекту Boxer, вероятно, понадобится ответить на оба вопроса . По разному . Это действительно хорошая причина дать им разные имена.
Я бы хотел сохранить
punch(boxer, object, strength)
и переименовать противоположный методpunched
. Вы могли бы назвать этоhandle_punch
или что-то в этом роде, но тогда все еще остается неоднозначным, обрабатывать ли это команду перфорации или уведомление о том, что она была перфорирована.источник
defend
в данном конкретном случае). Но боксерская груша никогда не будет такой двунаправленной. И уже есть этот файл .close () ...defend
это команда. Это одно из возможных действий, которое объект может выполнить в ответpunched
, но вы не хотели бы, чтобы другие объекты вызывалисьdefend
напрямую.Ваш подход в конечном итоге приведет к очень связанному коду.
Подводя итог, можно сказать, что в идеале Эрик Липперт хотел бы, чтобы боксер мог ударить по многим вещам. Наличие боксерской груши в качестве подписи функции боксера подразумевает, что боксер создан с немедленным знанием всего (что можно пробить). Плюс удар и получение удара - это две ОЧЕНЬ разные вещи, поэтому они не должны иметь одно и то же имя.
Я предпочел бы смоделировать это как боксера, который создает удар (другой объект, который содержит силу удара удара, направление, направление и т. Д.).
Затем используйте боксерскую грушу с помощью метода, такого как onPunch, который получает этот объект перфорации, чтобы вычислить эффект перфорации на себе.
Помня об этом, имя вещей имеет большое значение. Это должно соответствовать вашей ментальной модели ситуации. Если вы обнаружите, что пытаетесь объяснить, как что-то может произойти, что на первый взгляд не имеет смысла, или если вам тяжело назвать что-либо, тогда, возможно, ваша модель неправильна и должна измениться.
Трудно изменить модель после того, как вы начали, люди обычно склоняются к реальности, чтобы соответствовать модели. Проблема заключается в том, что по мере того, как вы сгибаете вещи, чтобы соответствовать (например, боксерской груше, которая может пробивать вещи), мир, который вы создаете, становится все более и более сложным, а взаимодействие становится все более и более трудным для реализации. В конечном итоге вы достигнете точки, когда добавление даже самых тривиальных вещей станет кошмаром изменений и ошибок. Эта концептуальная техническая задолженность может иметь очень высокую цену, даже если первоначальная стоимость в то время воспринималась как самая дешевая вещь.
источник
Это проблема, которую я называю «объект / субъект» путаница, и она довольно распространена.
У предложений обычно есть субъект, который делает глагол на их целевом объекте .
Что касается программирования, единственное, что на самом деле делает вещи - это компьютер. Или практически процесс, нить или волокно. Объекты не анимированы по умолчанию. У них нет собственных потоков, поэтому они ничего не могут сделать.
Это означает, что методы воздействуют на них, они являются целью действия, а не тем, кто выполняет действие. Вот почему мы называем их «объектами», а не «субъектами»!
Когда вы говорите
File.close
, что файл закрывается не сам, а текущий запущенный поток закрывает файл. Если вы говоритеArray.sort
, текущий запущенный поток сортирует массив. Если вы говоритеHttpServer.sendRequest
, текущий запущенный поток отправляет запрос на сервер (не наоборот!). Подобное высказываниеPunchingBag.punch
означает, что текущая бегущая нить пробивает мешок.Это означает, что если вы хотите,
Boxer
чтобыThread
функция была способна перфорировать, то она должна быть подклассом, чтобы она могла выполнять такие вещи, как перфорирование мешков в своей функции потока.Однако иногда также имеет смысл сказать, что боксерская груша пробивает себя в случае, когда у каждого объекта есть свой собственный поток, вы можете избежать условий гонки и реализовывать вызовы методов как передачу сообщений: вы
punch
пробиваете мешок, отправляя ему сообщение, это пробивает поток Затем сам отправляет вамpunch successful
сообщение, но это только детали реализации.источник
Я согласен с тем, что «punch» - это хорошее имя метода для класса Boxer, поскольку (с некоторыми изменениями) его можно повторно использовать против других объектов. Он также точно описывает, что объект класса выполняет действие над другим объектом. Хотя я бы переименовал метод в «doPunch», чтобы более четко продемонстрировать связь.
Однако для класса PunchingBag я нахожу имя метода слишком расплывчатым или немного неточным относительно того, что происходит в методе. Когда я вижу «удар», я думаю, что что-то пробивает что-то другое. Однако здесь объект PunchingBag реагирует на удар от объекта (в данном случае, объекта Boxer). Итак, я бы переименовал метод здесь в isPunched, чтобы проиллюстрировать, что объект реагирует на удар.
Хотя это моя интерпретация того, как я бы назвал методы. Все дело вкуса и стандартов, которым вы следуете.
источник
isPunched
действительно вводит в заблуждение (более или менее, в зависимости от схемы именования платформы).punch()
?хммм. Я подвергаю сомнению боксерскую грушу как класс, потому что вы действительно не заботитесь о боксерской груше - вы заботитесь о воздействии и силе кулака боксеров. таким образом, методы должны быть о том, что измеряет и сообщает о воздействии удара. даже если это исходит из «боксерской груши», наименование должно по-прежнему раскрывать ответственность - как punchImpactMeter и т. д.
источник
Боксер пробивает боксерскую грушу -> boxer.punch
Боксер пробивает боксерскую грушу -> punchingbag.get_punch
источник