Зачем придерживаться get-set, а не car.speed() и car.speed(55) соответственно?

StackOverflow https://stackoverflow.com/questions/2051713

Вопрос

Помимо однозначной ясности, почему мы должны придерживаться:
car.getSpeed() и car.setSpeed(55)
когда это также можно было бы использовать :car.speed() и car.speed(55)

Я знаю, что get() и set() полезны для обеспечения управляемости любыми изменениями в элементе данных, сохраняя все в одном месте.

Также, очевидно, я понимаю, что car.speed() и car.speed(55) являются ли то же самое функция, которая делает это неправильно, но затем в PHP, а также в Zend Framework, одно и то же действие используется для GET, POST, обратной отправки.
В VB и C # есть "свойства", и они используются многими, к большому неудовольствию пуристов, о которых я слышал, а в Ruby есть такие вещи, как 5.times и .each, .to_i и т.д.
И у вас есть перегрузка операторов, множественное наследование, виртуальные функции в C ++, определенные комбинации которых могут свести с ума кого угодно.

Я хочу сказать, что существует так много парадигм и способов, с помощью которых все делается, что кажется странным, что никто не попробовал ту конкретную комбинацию, о которой я упомянул.

Что касается меня, то моя причина в том, что это короткий и понятный для чтения код.
Я очень ошибаюсь, немного ошибаюсь, это просто странно и поэтому не используется, или что еще?

Если я все еще решу оставаться корректным, я мог бы использовать car.speed() и car.setSpeed(55).
Это в чем-то неправильно (просто опуская "get")?

Спасибо за любые объяснения.

Это было полезно?

Решение

Если бы я вызвал car.speed(), я мог бы подумать, что говорю машине прибавить скорость, другими словами, увеличить скорость и нарушить скоростной режим.Это явно не добытчик.

Некоторые языки позволяют вам объявлять объекты const, а затем ограничивать вас только вызовом функций, которые не изменяют данные объекта.Таким образом, необходимо иметь отдельные функции для операций модификации и чтения.Хотя вы могли бы использовать перегрузки для параметров для выполнения двух функций, я думаю, это сбило бы с толку.

Кроме того, когда вы говорите, что это понятнее для чтения, я могу возразить, что мне нужно заглянуть вперед, чтобы понять, как это читать:

car.speed()

Я читаю "скорость автомобиля ...", а потом вижу, что там нет цифры, поэтому я пересматриваю и думаю "получить скорость автомобиля".

car.getSpeed()

Я прочитал "для этой машины набери скорость".

car.setSpeed(55)

Я прочитал "для этой машины установите скорость на 55".

Кажется, вы в основном ссылались на другие особенности языка как на сбивающие с толку, а затем использовали это в качестве защиты для того, чтобы сделать геттеры / сеттеры более запутанными?Это звучит почти как признание того, что то, что вы предложили, еще больше сбивает с толку.Эти функции иногда сбивают с толку из-за того, насколько они универсальны.Иногда абстракции могут быть более запутанными, но в конечном итоге они часто служат цели более многократного использования.Я думаю, если бы вы хотели привести доводы в пользу speed() и speed(55), вы бы хотели показать, как это может открыть новые возможности для программиста.

С другой стороны, C # действительно имеет нечто подобное тому, что вы описываете, поскольку свойства ведут себя по-разному как средство получения или установки в зависимости от контекста, в котором они используются:

Console.WriteLine(car.Speed); //getter

car.Speed = 55 //setter

Но хотя это одно свойство, есть два отдельных раздела кода для реализации получения и настройки, и ясно, что это средство получения / установки, а не скорость функции, потому что они опускают () для свойств.Таким образом, car.speed() явно является функцией, а car.speed явно является средством получения свойств.

Другие советы

ИМХО, стиль C #, в котором свойства используются в качестве синтаксического сахара для методов get и set, является наиболее выразительным.

Я предпочитаю активные объекты, которые инкапсулируют операции, а не геттеры и сеттеры, так что вы получаете семантически более богатые объекты.

Например, хотя ADT, а не бизнес-объект, даже vector в C ++ есть парные функции:

size_type capacity() const // how many elements space is reserved for in the vector  
void reserve(size_type n)  // ensure space is reserved for at least n elements 

и

void push_back ( const T& ) // inserts an element at the end
size_type size () const     // the number of elements in the vector

Если вы ведете автомобиль, вы можете настроить акселератор, сцепление, тормоза и передачу, но вы не устанавливаете скорость.Вы можете считывать скорость по спидометру.Относительно редко требуется использовать как установщик, так и получатель для объекта с поведением.

К вашему сведению, Objective-C использует car.speed() и car.setSpeed(55) (за исключением другого синтаксиса, [car speed] и [car setSpeed:55].

Все дело в условностях.

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

FWIW Я предпочитаю класс.существительное() для добытчика, и класс.глагол() для сеттера.Иногда глаголом является просто setNoun(), но в других случаях нет.Это зависит от существительного.Например:

my_vector.size() 

возвращает размер, и

my_vector.resize(some_size) 

изменяет размер.

Заводной подход к свойствам довольно превосходный, ИМХО, http://groovy.codehaus.org/Groovy+Beans

Окончательными контрольными показателями вашего кода должно быть следующее:

  1. Правильно ли это работает?
  2. Легко ли это починить, если оно сломается?
  3. Легко ли добавлять новые функции в будущем?
  4. Легко ли кому-то другому прийти и исправить / улучшить это?

Если эти 4 пункта будут учтены, я не могу представить, почему у кого-то могут возникнуть проблемы с этим.Большинство "наилучших практик", как правило, направлены на достижение этих 4 пунктов.

Используйте любой стиль, который вам подходит, просто будьте последовательны в этом, и все будет в порядке.

Это всего лишь условность.В Smalltalk это делается так, как вы предлагаете, и я не помню, чтобы когда-либо слышал, чтобы кто-нибудь жаловался на это.Получение скорости автомобиля - это car speed, а установка скорости автомобиля на 55 - это car speed:55.

Если бы я рискнул высказать предположение, я бы сказал, что причина, по которой этот стиль не прижился, заключается в двух строках, по которым к нам пришло объектно-ориентированное программирование:C++ и Objective-C.В C ++ (тем более на ранних этапах его истории) методы очень тесно связаны с функциями C, а функции C традиционно именуются следующим образом setWhatever() и не иметь перегрузки для разного количества аргументов, так что общий стиль именования был сохранен.Objective-C был в значительной степени сохранен NeXT (которая позже стала Apple), и NeXT предпочитала многословие в своих API и особенно проводить различие между различными типами методов — если вы делаете что-либо, кроме простого доступа к свойству, NeXT хотел, чтобы глагол прояснял это.Так что это стало соглашением в Cocoa, которое в наши дни является де-факто стандартной библиотекой для Objective-C.

Это соглашение Java имеет соглашение о получателях и установщиках, C # имеет свойства, python имеет общедоступные поля, а фреймворки JavaScript, как правило, используют field() для получения и field (значение) для установки

Помимо однозначной ясности, почему мы должны придерживаться:car.getSpeed() и car.setSpeed(55) когда это также можно было бы использовать :car.speed() и car.speed(55)

Потому что на всех языках, с которыми я сталкивался, car.speed() и car.speed(55) одинаковы с точки зрения синтаксиса.Просто глядя на них таким образом, оба могут возвращать значение, что неверно для последнего, если оно должно было быть установщиком.

Что делать, если вы намереваетесь вызвать установщика, но забыли ввести аргумент?Код является допустимым, поэтому компилятор не жалуется и не выдает немедленную ошибку времени выполнения;это бесшумный жук.

.() означает, что это глагол.no () означает, что это существительное.

   car.Speed = 50;
   x = car.Speed
   car.Speed.set(30)
   car.setProperty("Speed",30)

но

   car.Speed()

подразумевает команду на превышение предельной скорости.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top