Каков наилучший подход для реализации методов включения / выключения в Java? - PullRequest
2 голосов
/ 17 апреля 2011

В Java, учитывая пару открытых методов, enableFoo и disableFoo, которые устанавливают логическое поле с именем isEnabledFoo равным true или false, соответственно, должен ли метод проверять, чтобы увидеть, включен ли Foo перед установкой? Если да, должно ли быть выдано исключение? Если да, следует ли это проверять или не проверять? Если не проверено, что это должно бросить? IllegalStateException

Подсказка: хотя текущая реализация просто устанавливает логическое поле, я намеренно не реализую его как один метод setFoo "setter" с логическим параметром, потому что реализация может быть изменена позже, чтобы включить побочные эффекты (возможно, даже не установка поля вообще). Сохранение его как enableFoo / disableFoo казалось лучшим способом гарантировать инкапсуляцию.

Должен ли я сделать это:

public void enableFoo() throws myCheckedException
{
  if (! this.isEnabledFoo)
  {
    this.isEnabledFoo = true;
  }
  // Is this overkill?
  else
  {
    // Foo is already enabled...Should a checked exception be thrown?
    throw new myCheckedException ("Foo is already enabled.");

    // What about an unchecked exception?
    // throw new IllegalStateException ("Foo is already enabled.");
  }
}

или просто так:

public void enableFoo()
{
  // I guess we don't care if foo is already enabled...
  this.isEnabledFoo = true;
}

или даже:

public void enableFoo()
{
  // Is this just code bloat?
  if (! this.isEnabledFoo)
  {
    this.isEnabledFoo = true;
  }
}

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

Ответы [ 4 ]

4 голосов
/ 17 апреля 2011

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

Например: у меня есть метод, который включает подсветку синтаксиса, если вы решите включить его, и он уже включен, что бы вы заботились. В таком случае вы просто устанавливаете логический флаг независимо от предыдущего состояния (вариант 2).

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

Примерно так:

public void enableHighlighting() {
  if (!isHighlighting) {
    isHighlighting = true;
    colorView();  // very expensive method
  }
}

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

Например, скажем, подсветка синтаксиса влияет только на определенные типы файлов, такие как код XML или Java, и пользователь пытается применить его к коду PHP. Теперь выделение уже включено, но разочарованный пользователь пытается включить его, потому что он не видит никаких изменений. В таком случае вы можете напечатать пользователю сообщение о том, что выделение уже включено. В таком случае возвращаемое значение того, произошло ли изменение, вероятно, будет иметь больше смысла, но вы также можете использовать исключение.

Возвращаемое значение:

public boolean enableHighlighting() {
  prevState = isHighlighting;
  isHighlighting = true;
  return prevState != isHighlighting; //return true if value changed
}
0 голосов
/ 17 апреля 2011

Нет прямого ответа.Это зависит от требований.В частности, является ли ваша операция идемпотентной.

http://en.wikipedia.org/wiki/Idempotence

0 голосов
/ 17 апреля 2011

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

0 голосов
/ 17 апреля 2011

Неа.Почему ты должен заботиться?enableFoo и disableFoo очень явные - один включает, другой отключает.Не нужно проверять текущее состояние.

Если вы действительно хотите, вы можете вернуть логическое значение, которое указывало бы на предыдущее состояние.Вы также можете использовать метод public boolean isEnabled().

...