Я часто создаю классы, которые используют эту форму (A):
abstract class Animal {
public void Walk() {
// TODO: do something before walking
// custom logic implemented by each subclass
WalkInternal();
// TODO: do something after walking
}
protected abstract void WalkInternal();
}
class Dog : Animal {
protected override void WalkInternal() {
// TODO: walk with 4 legs
}
}
class Bird : Animal {
protected override void WalkInternal() {
// TODO: walk with 2 legs
}
}
Вместо этой формы (B):
abstract class Animal {
public abstract void Walk();
}
class Dog : Animal {
public override void Walk() {
// TODO: do something before walking
// custom logic implemented by each subclass
// TODO: walk with 4 legs
// TODO: do something after walking
}
}
class Bird : Animal {
public override void Walk() {
// TODO: do something before walking
// custom logic implemented by each subclass
// TODO: walk with 2 legs
// TODO: do something after walking
}
}
Как Вы видите, хорошая вещь о форме A состоит в том, что каждый раз Вы реализуете подкласс, Вы не должны помнить включать логику инициализации и завершения. Это намного менее подвержено ошибкам, чем форма B.
Что такое стандартная конвенция для именования этих методов?
Мне нравится называть открытый метод Walk
с тех пор я могу звонить Dog.Walk()
который выглядит лучше, чем что-то как Dog.WalkExternal()
. Однако я не люблю своего решения добавления суффикса, "Внутреннего" для защищенного метода. Я ищу более стандартизированное имя.
Btw, там название этого шаблона разработки?
Я не уверен, что для этого существует стандартное соглашение об именовании. Кроме WalkInternal
, другими альтернативами могут быть DoWalk
или WalkImpl
.
Я использую соглашение о подчеркивании с заглавной буквы для абстрактных переопределений, так что Dog._Walk, хотя я более чем иногда задаюсь вопросом, нет ли лучшего способа.
Мне нравится DoWalk больше, чем WalkInternal - он короче и передает идею о том, что его можно отменить быстро и заранее. «Делай» что-то меня неправильно трёт, вроде как «Мой» объект. И все же мне больше всего нравится мое подчеркивание, сопровождаемое условным обозначением заглавных букв.
Хороший вопрос из реальной жизни
Ура,
Беррил
Методы - это средства выполнения действий, и, следуя этому правилу, имена методов должны быть либо глагольными, либо глагольными фразами. И это применимо к методам независимо от того, где они объявлены . Для меня Dog.Walk выглядит более естественным, чем Dog.WalkInternal. И да, наименование метода - это скорее рекомендация, чем шаблон дизайна :). Если вы парень .Net, то я порекомендую книгу "Framework Design GuideLines" автора Брэд Адам и Кшиштоф Квалина, которые явно решают такие проблемы.
Хороший вопрос. Шаблон действующий, и я его много использую. Я также согласен с тем, что WalkInternal
- не идеальное имя.
В этом примере я считаю, что вы неправильно формулируете проблему.
Вместо того, чтобы переименовывать «внутренний» метод, посмотрите на свой «внешний» общедоступный метод. Он называется Walk
, но в нем есть фрагменты кода ( // делать что-то перед ходьбой
и // делать что-то после ходьбы
), которые ясно показывают, что он содержит больше, чем просто логика «ходьбы». Может быть, этот метод следует называть Exercise
или GoToTheShops
- или любое другое творческое название, которое, как вы можете придумать, описывает то, что вы делаете. Каким бы ни был метод, это определенно надмножество ходьбы + некоторых других действий до и после ходьбы.
В похожем примере, который я недавно разработал, был общедоступный метод под названием Complete
и виртуальный под названием Save
, так что:
В итоге абстрактный метод должен называться Walk
, а вместо этого вам следует переименовать свой общедоступный метод во что-то, что более точно описывает процесс «делать что-то / ходить / делать что-то».
править: Если класс Walk
не добавляет каких-либо значимых значений или логики к классу WalkInternal
, то я бы задал вопрос, требуется ли это. Если он добавляет логику, его следует переименовать, чтобы отразить его новую функцию.
Кстати, есть ли название для этого шаблона проектирования?
Ваш первый пример использует аспекты шаблона Template Method и похож на то, что Херб Саттер называет "идиомой невиртуального интерфейса":
Я предпочитаю называть свои виртуальные или абстрактные методы суффиксом Core
, чтобы указать, что должен содержать основную логику, чтобы что-то делать.
Все проверки аргументов и вызов возможных событий я выполняю в методе, вызывающем Core-Methods.
abstract class Animal {
public void Walk() {
// TODO: do something before walking
// possible Argument checks and event raising
// custom logic implemented by each subclass
WalkCore();
// TODO: do something after walking
}
protected abstract void WalkCore();
}
class Dog : Animal {
protected override void WalkCore() {
// TODO: walk with 4 legs
}
}
class Bird : Animal {
protected override void WalkCore() {
// TODO: walk with 2 legs
}
}
Я думаю, что для этого не существует официального руководства по именованию, и решать вам. Но он должен быть согласован для всех классов и виртуальных / абстрактных методов, которые вы определяете.
В «Руководстве по проектированию инфраструктуры» предлагается использовать суффикс Core , если вы следуете шаблонному методу и хотите обеспечить возможности расширения.