• Как вы называете парные методы Get/Set? Допускается ли делать их несимметричными? А если для свойства используется глагол Is? А если какой-нибудь модальный глагол вроде Can?
  • Допускается ли вместо Get/Set использовать пары Is/Set?
  • И если есть ограничения, то это ваш сознательный выбор или корпоративный стандарт?


У нас в компании по этому поводу написано следующее (выдержка из инструкции программиста, часть «Рекомендация по образованию имен»):

Методы получения бинарного атрибута

Имя метода получения бинарного атрибута должно быть предикатом (вопросом, на который можно ответить Да или Нет). В большинстве случаев имя метода должно начинаться с глаголов Is или Has.

Методы получения и установки небинарного атрибута

Допускается добавление к названию метода получения атрибута глагола Get. Если кроме метода получения атрибута в классе есть также метод установки атрибута, то названия этих методов должны начинаться с глаголов Get и Set соответственно.

Теперь же возьмём открытое у меня «произвольное» решение, состоящее примерно из 50 проектов, большей частью касающихся оболочки продукта, и включающее в себя около 5000 заголовочный файлов. И посмотрим, какие именования там встречаются:



На круговой диаграмме показано относительное распределение различных “get”-методов. На остальных по смысловым глаголам: Is, Can, Has, Need, Should. Только будьте внимательны, некоторые диаграммы строил грамотный PM.

Анализ найденного показал, что есть небольшое число парных Is/Set методов, у которых метод Set не принимает никаких параметров. Т.е. значение по умолчанию false, а set-метод его взводит, и отменить данный переход никак нельзя. Это осмысленно для IsFailed() / SetFailed(). Но во многих случаях данное ограничение вытекает скорее из ограничений UI (что сейчас пользователь так не может сделать), чем из логики свойства.

Также надо заметить, что поиск по чужому решению показал кардинально отличающееся распределение. Поэтому использование конкретных модальных глаголов, скорее всего, связано с людьми в команде, чем c правилами организации.

Так как же правильно назвать метод? NeedDoSomething или ShouldDoSomething? Какой модальный глагол выбрать? Попробуем ответить на этот вопрос. Совершенно очевидно, что таких методов должно быть шесть, а как их использовать указано ниже:



bool Do( TАction type, IObject* obj ) {
  // надо ли вообще париться
  if( !detector.ShouldDo( type, obj ) ) {
    return false;
  }

  // разрешено ли действие
  if( !callback.MayDo( type, obj ) && !DareToDo( type ) ) {
    // нам запретили выполнить действие и у нас нет смелости нарушить указание
    // проверим на обязательность действия – и кинем исключение, если надо
    check( !detector.MustDo( type, obj ), ERR_MUST_NOT_MAY );
    return false;
  }

  // выполним действие
  foreach( executor in executors ) {
    if( executor.OughtToDo( type, obj ) ) {
      if( executor.CanDo( obj ) ) {
        executor.Do( obj );
      }
      check( !detector.MustDo( type, obj ), ERR_MUST_NOT_CAN );
      return false;
    }
  };

  // executor должен быть
  check( false, ERR_EXEC_NOT_FOUND );
}

Комментарии (24)


  1. apro
    22.02.2018 13:16

    В этом контексте есть интересный blog post: getters-and-setters-are-evil,
    цитата оттуда:


    Can a living organism have a setter? Can you "set" a ball to a dog? Not really. But that is exactly what the following piece of software is doing:
    Dog dog = new Dog();
    dog.setBall(new Ball());
    How does that sound?


    Can you get a ball from a dog? Well, you probably can, if she ate it and you're doing surgery. In that case, yes, we can "get" a ball from a dog. This is what I'm talking about:


    1. Zordhauer
      23.02.2018 10:56

      Спасибо за статью)
      Тот случай, когда читать материал по ссылкам из комментариев интереснее, чем статью над комментариями.


  1. andreymal
    22.02.2018 13:24
    +1

    Проблемы джавистов… Нормальные люди на нормальных языках программирования просто создают свойство isCorrect и спокойно пишут что-то вроде obj.isCorrect = true :)


    1. lgorSL
      22.02.2018 13:36

      Проблемы джавистов…

      В примере код на C++


    1. JC_IIB
      22.02.2018 13:37

      Нормальные люди пишут на нормальных языках программирования, где by design нет ни классов, ни, прости господи, мутабельности :)


      1. JC_IIB
        22.02.2018 13:44

        p.s. прошу на шутку (а это именно она) не обижаться, особенно питонистов и сопричастных :)


      1. TheShock
        23.02.2018 07:00

        Нормальные люди пишут на нормальных языках программирования, где by design нет ни классов, ни, прости господи, мутабельности :)

        Ага, и называют методы, переменные и все остальное так, что без поллитры не разберешься. Что делают функции с названием pipe, it, connect, put, dispatch?


        1. JC_IIB
          23.02.2018 10:50

          Нет там переменных. И методов тоже нет :)


          1. TheShock
            23.02.2018 18:28

            Да, в целом вы правы (все-таки 7 утра было, время уже было идти спать), но идею вы поняли.


            1. JC_IIB
              23.02.2018 18:39

              А именовать функции понятно — это задача и проблема программиста, а не языка.


              1. TheShock
                23.02.2018 18:43

                Какие языки — такие программисты.


                1. SantaCluster
                  23.02.2018 19:48

                  по-моему, наоборот: какие программисты, такие и языки


    1. Neikist
      22.02.2018 15:15

      Слишком толсто. Можно холивар разжечь если кто нибудь подумает что вы это всерьез.


    1. kosmonaFFFt
      22.02.2018 16:11
      +1

      У нас нет проблем, у насть есть JavaBeans стандарт. Он говорит про get/set в общем, и про возможность наличия is/set для булевых свойств (хотя можно и get/set).
      А от языков это не зависит, JavaBean может быть скомпилирован из любого языка.


  1. Xalium
    22.02.2018 16:22
    +1

    В большинстве случаев имя метода должно начинаться с глаголов Is или Has.

    А как обзывать переменную, которой присваивается результат выполнения данного метода?


    1. rraderio
      22.02.2018 17:29

      А зачем переменная?

      boolean hasElements() {
          return !isEmpty();
      }
      


      1. Xalium
        22.02.2018 21:07

        Если для нижележащего кода точно известно, что это значение не изменится и это значение используется несколько раз, то нашиша каждый раз вызывать какую-либо функцию? Менее затратно присвоить значение переменной.


  1. neurocore
    23.02.2018 06:38

    Мне кажется get — это своеобразное fallback имя метода. Если можно другими словами более конкретно суть происходящего в методе, то лучше так и сделать. Например, getPrice — это явное получение поля, но hasCheck — выяснение, есть ли шах на доске, то есть по сути это действие подразумевает вычисление.


  1. calg0n
    23.02.2018 10:18

    Если возвращается bool, То логичней использовать is, has, can, should. В остальных случаях getИмяСвойства().
    По поводу set всё не так однозначно. С одной стороны должно быть setИмяСвойства(), но с другой setIsActive() звучит странновато. Думаю можно использовать глаголы для булевых свойств аля activate() -> выставляет is_active = true, verifyAddress() -> выставляет is_address_verified = true. Также строгое именование setИмяСвойства/getИмяСвойства частенько требует фреймворк например при создании entity.


    1. vitaliy2
      23.02.2018 20:28

      Сравните:
      setIsOldValue
      setOldValue

      Думаю, разница очевидна =)


      1. parmactep
        24.02.2018 01:52

        Определенно напрашиваются разные типы.


      1. RouR
        25.02.2018 13:45

        markAsOldValue


    1. parmactep
      24.02.2018 01:55

      Что мешает использовать для isActive глаголы toggle или change.


      1. calg0n
        24.02.2018 10:08

        Тоже отличный вариант.