Являются методы считывания и методы set плохим дизайном? Противоречащий замеченный совет [копирует]

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

В текущей конфигурации это то же самое, что и проверка, является ли цель действительно #main, a.k.a jQuery's $ event.currentTarget .

$('#main').on('mousemove', function(e) {
  // here we only want the events of #main
  // so any other target is irrelevant
  if (e.target !== e.currentTarget) return;
  var msg = "mouse move ";
  msg += e.pageX + ", " + e.pageY;
  $("#output").html(msg);
});
$('#main').on('mouseout', function() {
  $("#output").html('');
});
$('#main>.btn').on('click', e=> $("#output").html('can still click'));
#main {
  float: left;
  background: yellow;
  width: 400px;
  height: 400px;
  position: relative;
}

#main .btn {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 2;
  border: 0;
  background: blue;
  color: #FFF;
}

#main .btn .innerbtn {
  padding: 10px;
}

#output {
  display: inline-block;
  background: #efefef;
  width: 200px;
  position: absolute;
  right: 0;
  pointer-events: none;
}

Click Me

224
задан cнŝdk 9 October 2018 в 22:49
поделиться

14 ответов

Существует также точка зрения, которая большую часть времени, с помощью методов set все еще повреждает инкапсуляцию путем разрешения Вам установленным значениям, которые бессмысленны. Как очень очевидный пример, если у Вас есть счетчик счета на игре, которая только когда-либо повышается, вместо

// Game
private int score;
public void setScore(int score) { this.score = score; }
public int getScore() { return score; }
// Usage
game.setScore(game.getScore() + ENEMY_DESTROYED_SCORE);

, это должно быть

// Game
private int score;
public int getScore() { return score; }
public void addScore(int delta) { score += delta; }
// Usage
game.addScore(ENEMY_DESTROYED_SCORE);

, Это - возможно, определенный поверхностный пример. То, что я пытаюсь сказать, - то, что обсуждение метода считывания/методов set по сравнению с общедоступными полями часто затеняет большие проблемы с объектами, управляющими внутренним состоянием друг друга близким способом и следовательно быть слишком тесно связанным.

идея состоит в том, чтобы сделать методы, которые непосредственно делают вещи, которые Вы хотите сделать. Пример был бы то, как установить "живое" состояние врагов. Вы могли бы испытать желание иметь setAlive (живая булевская переменная) метод. Вместо этого Вы должны иметь:

private boolean alive = true;
public boolean isAlive() { return alive; }
public void kill() { alive = false; }

причина этого состоит в том, что при изменении реализации, что вещи больше не имеют "живую" булевскую переменную, а скорее значение "очков жизни", можно менять это, не нарушая условия контракта этих двух методов, которые Вы записали ранее:

private int hp; // Set in constructor.
public boolean isAlive() { return hp > 0; } // Same method signature.
public void kill() { hp = 0; } // Same method signature.
public void damage(int damage) { hp -= damage; }
344
ответ дан Zarkonnen 23 November 2019 в 03:56
поделиться

Я программировал в Java для несколько месяцев назад, и я узнал, что мы должны использовать методы считывания & методы set только, когда это необходимо для приложения

, весело проводят время :)

0
ответ дан Giancarlo 23 November 2019 в 03:56
поделиться

При необходимости во внешнем доступе к отдельным значениям полей используйте методы считывания и / или методы set. В противном случае не делайте. Никогда не используйте общедоступные поля. Это настолько просто! (Хорошо, это никогда не , что простой, но это - хорошее эмпирическое правило).

В целом необходимо также найти, что необходимо предоставлять метод set намного менее часто, чем метод считывания - особенно, при попытке сделать свои объекты неизменными - который является Хорошей Вещью (но не всегда лучшим выбором) - но даже если нет.

1
ответ дан philsquared 23 November 2019 в 03:56
поделиться

Можно хотеть заменить некоторые классы классами значения. Это позволит Вам удалять метод считывания и избегать проблем, когда содержание будет изменено из-под Вас.

1
ответ дан David Segonds 23 November 2019 в 03:56
поделиться

Просто к вашему сведению: В дополнение ко всем превосходным ответам в этом потоке помните поток всех причин, которые можно придумать за или против методов считывания/методов set, производительность не одна (как некоторые могли бы полагать). JVM достаточно умна для встраивания тривиальных методов считывания/методов set (даже не - final, пока они на самом деле не переопределяются).

2
ответ дан gustafc 23 November 2019 в 03:56
поделиться

Это зависит от рассматриваемого языка программирования. Ваш вопрос структурирован в контексте Java, где кажется, что методы считывания и методы set обычно считаются хорошей вещью.

Напротив, в мире Python, их обычно рассматривают как плохой стиль: они добавляют строки к коду, на самом деле не добавляя функциональность. Когда Python программисты должны, они могут использовать метапрограммирование для ловли получения и/или установки атрибутов объектов.

В Java (по крайней мере, версия Java я учился немного десятилетие назад), который не был возможен. Таким образом в Java обычно лучше использовать методы считывания и методы set неукоснительно, так, чтобы, если Вы должны, можно было переопределить доступ к переменным.

(Это не делает Python обязательно лучше, чем Java, просто отличающийся.)

3
ответ дан 23 November 2019 в 03:56
поделиться

Мое мнение - то, что методы считывания и методы set являются требованием для хороших программ. Палка с ними, но не пишут ненужные методы считывания/методы set - не всегда необходимо непосредственно иметь дело со всеми переменными.

10
ответ дан Joonas Pulakka 23 November 2019 в 03:56
поделиться

Поскольку всегда единственный ответ: это зависит. Если Вы - единственный peron касание кода, можно сделать что-либо, что Вы довольны, включая поиск легких путей.

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

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

4
ответ дан Jeroen van Bergen 23 November 2019 в 03:56
поделиться

Ваш Игровой класс, вероятно, следует объект бога антишаблон, если он выставляет это много переменных. Нет ничего неправильно с методами считывания и методами set (хотя их многословие в Java может быть немного раздражающим); в хорошо разработанном приложении, где каждый класс имеет ясно разделенную функциональность, Вам не будут нужны десятки из них в едином классе.

Редактирование: , Если основной момент для методов считывания и методов set должен "настроить" игру Classe (я понимаю Ваш комментарий, что путь), затем Ваш, вероятно, не нуждаются в методах считывания (это прекрасно подходит классу для доступа к его собственным частным переменным без использования, получают методы), и можно, вероятно, свернуть многие методы set в "методы set группы", которые устанавливают несколько переменных, которые принадлежат вместе концептуально.

15
ответ дан Michael Borgwardt 23 November 2019 в 03:56
поделиться

Это - скользкий путь.

А простой объект Передачи (или Объект параметра) может иметь единственную цель содержать некоторые поля и обеспечить их значения по требованию. Однако даже в том вырожденном случае можно было утверждать, что объект должен быть неизменным - настроенный в конструкторе и представлении только get... методы.

Там также имеет место класса, который выставляет некоторые "ручки управления"; UI Вашего автомобильного радиоприемника, вероятно, может быть понят как представление чего-то как getVolume, setVolume, getChannel, и setChannel, но его реальная функциональность получает сигналы и испускает звук. Но те кнопки не выставляют много детали реализации; Вы не знаете от тех интерфейсных функций, является ли радио транзисторами, главным-образом-программным-обеспечением или вакуумными лампами.

, Чем больше Вы начинаете думать об объекте как активный участник задачи проблемной области, тем больше Вы будете думать с точки зрения выяснения у него к , делают что-то вместо того, чтобы просить, чтобы это сказало Вам о его внутреннем состоянии или выяснении у него для его данных так , другой код может сделать что-то с теми значениями.

Так... "зло"?Не совсем. Но каждый раз Вы склонны вставить значение и выставить и get... и set... методы на том значении, спросить себя, почему, и каков reponsibility того объекта действительно. Если единственный ответ, который можно дать сами, "Для содержания этого значения для меня", затем , возможно что-то помимо OO продолжается здесь.

19
ответ дан joel.neely 23 November 2019 в 03:56
поделиться

Методы считывания и методы set осуществляют понятие [1 114] инкапсуляция в объектно-ориентированном программировании.

При наличии состояний объекта, скрытого от внешнего мира, объект действительно отвечает за себя и не может быть изменен способами, которые не предназначаются. Единственными путями объектом можно управлять, через выставленные открытые методы, такие как методы считывания и методы set.

существует несколько преимуществ для того, чтобы иметь методы считывания и методы set:

1. Разрешение будущего изменяется без модификации для кодирования, который использует измененный класс.

Одно из большого преимущества использования метода считывания и метода set - то, что, после того как открытые методы определяются, и там прибывает время, когда конкретная реализация должна быть изменена (например, нахождение ошибки, которая должна быть исправлена, с помощью другого алгоритма для того, чтобы улучшить производительность, и т.д.), при наличии методов считывания и методов set быть единственным способом управлять объектом, это позволит существующему коду не повреждаться, и работать как ожидалось даже после изменения.

, Например, скажем, существует setValue метод, который устанавливает value частная переменная в объекте:

public void setValue(int value)
{
    this.value = value;
}

, Но затем, было новое требование, которое должно было отслеживать количество раз value, был изменен. С методом set на месте, изменение довольно тривиально:

public void setValue(int value)
{
    this.value = value;
    count++;
}

, Если value поле было общедоступно, нет никакого простого способа возвратиться позже и добавить счетчик, который отслеживает количество раз, значение было изменено. Поэтому наличие методов считывания и методов set является одним способом "соответствовать требованиям завтрашнего дня" класс для изменений, которые могут прибыть позже.

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

Другой способ, которым пригождаются методы считывания и методы set, состоит в том, чтобы осуществить способы, которыми объектом можно управлять, поэтому, объект контролирует свое собственное состояние. С общедоступными переменными выставленного объекта это может легко быть повреждено.

, Например, ImmutableArray объект содержит int массив, названный myArray. Если массив был общедоступным полем, это просто не будет неизменно:

ImmutableArray a = new ImmutableArray();
int[] b = a.myArray;
b[0] = 10;      // Oops, the ImmutableArray a's contents have been changed.

Для реализации действительно неизменного массива метод считывания для массива (getArray метод) должен быть записан так, он возвращает копию своего массива:

public int[] getArray()
{
    return myArray.clone();
}

И даже если следующее происходит:

ImmutableArray a = new ImmutableArray();
int[] b = a.getArray();
b[0] = 10;      // No problem, only the copy of the array is affected.

Эти ImmutableArray действительно неизменно. Представление переменных объекта позволит этому управляться способами, которые не предназначаются, но только представление определенных путей (методы считывания и методы set), объектом можно управлять намеченными способами.

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

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

28
ответ дан coobird 23 November 2019 в 03:56
поделиться

У Вас уже было много хороших ответов на этом, таким образом, я просто дам свои два цента. Методы считывания и методы set очень, очень злые. Они по существу позволяют Вам симулировать скрывать внутренности своего объекта, когда большую часть времени все, что Вы сделали, брошено в избыточном коде, который не делает ничего для сокрытия внутреннего состояния. Для простого POJO нет никакой причины, почему getName () и setName () не может быть заменен obj.name = "Tom".

, Если вызов метода просто заменяет присвоение, то все Вы получили путем предпочтения вызова метода, чрезмерное увеличение размера кода. К сожалению, язык хранил использование методов считывания и методов set в спецификации JavaBeans, таким образом, программисты Java вынуждены использовать их, даже когда выполнение так не имеет никакого смысла вообще.

, К счастью, Eclipse (и вероятно другие IDE также) позволяет Вам автоматически генерировать их. И для забавного проекта, я когда-то создал генератор кода для них в XSLT. Но если бы существует одна вещь, я избавился бы от в Java, это - сверхзависимость от методов считывания и методов set.

46
ответ дан rtperson 23 November 2019 в 03:56
поделиться
  • Очень злой: общедоступные поля.
  • Несколько злой: Методы считывания и методы set, где они не требуются.
  • Хороший: Методы считывания и методы set только там, где они действительно требуются - заставляют тип выставить "большее" поведение, которое происходит с использование его состояние, вместо того, чтобы просто рассматривать тип как репозиторий состояния, которым будут управлять другие типы.

Это действительно зависит от ситуации, хотя - иногда Вы действительно делаете , просто хотят немой объект данных.

181
ответ дан Jon Skeet 23 November 2019 в 03:56
поделиться

Присутствие метода считывания и методов set имеет тенденцию указывать ("запах", если Вы на такой язык начальной школы), что существует проблема проектирования. Тривиальные методы считывания и методы set едва различимы от общедоступных полей. Обычно код, воздействующий на данные, будет в другом классе - плохая инкапсуляция, и что Вы ожидали бы от программистов не непринужденно с OO.

В некоторых случаях методы считывания и методы set прекрасны. Но как правило тип и с методами считывания и с методами set указывает на проблемы проектирования. Методы считывания работают на неизменность; работа методов set для "говорит, не спрашивают". И неизменность и "говорит, не спрашивают", хорошие проектные решения, пока они не применяются в перекрывающемся стиле.

11
ответ дан Tom Hawtin - tackline 23 November 2019 в 03:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: