Tell-Don’t-Ask

http://martinfowler.com/bliki/TellDontAsk.html
  • Перевод
  • Tutorial
Tell-Don’t-Ask является принципом, который помогает вспомнить, что объектно-ориентированное программирование предназначено для связки данных и функций для их обработки. Он напоминает нам, что вместо того, чтобы спрашивать данные у объекта, мы должны сказать объекту что с ними делать. Для этого все поведение объекта надо заключить в его методы.
image

Разберемся на примере. Давайте представим, что нам нужно контролировать сигнализацию, которая сработает, если число поднимется выше определенной планки. Если мы напишем это в стиле «ask», мы получим структуру данных…
class AskMonitor...
  private int value;
  private int limit;
  private boolean isTooHigh;
  private String name;
  private Alarm alarm;

  public AskMonitor (String name, int limit, Alarm alarm) {
    this.name = name;
    this.limit = limit;
    this.alarm = alarm;
  }

… затем совместим это с методами доступа к данным:
class AskMonitor...
  public int getValue() {return value;}
  public void setValue(int arg) {value = arg;}
  public int getLimit() {return limit;}
  public String getName()  {return name;}
  public Alarm getAlarm() {return alarm;}

И использовали бы это так:
    AskMonitor am = new AskMonitor("Time Vortex Hocus", 2, alarm);
    am.setValue(3);
    if (am.getValue() > am.getLimit()) 
      am.getAlarm().warn(am.getName() + " too high");

«Tell-Don’t-Ask» напоминает нам, что поведение следует описать внутри объекта(используя те же поля):
class TellMonitor...
  public void setValue(int arg) {
    value = arg;
    if (value > limit) alarm.warn(name + " too high");
  }

И это будет работать так:
    TellMonitor tm = new TellMonitor("Time Vortex Hocus", 2, alarm);
    tm.setValue(3);

Многие люди находят принцип «Tell-Don’t-Ask» полезным. Одним из фундаментальных принципов объекто-ориентированного дизайна является совмещение данных и поведения, поэтому простые элементы системы (объекты) совмещают это в себе. Часто это хорошо, потому что данные и их обработка тесно связанны: изменения в одном вызывают изменения в других. Вещи, которые тесно связанны должны быть одним компонентом. Помнить об этом принципе поможет программистам увидеть, как можно совмещать данные и поведение.

Но лично я не использую этот принцип. Я просто стараюсь размещать в одном месте данные и поведение, что часто ведет к тем же результатам. Одна из проблем — этот принцип стимулирует людей убирать методы запрашивающие информацию. Но бывает, когда объекты эффективно сотрудничают предоставляя информацию. Хорошим примером будут объекты, упрощающие информацию для других объектов. Я видел код, который на столько закручен, что подходящие запрашивающие методы решили бы эту проблему. Для меня «Tell-Don't-Ask» шаг к объединению поведения и данных, но это не первоочередная задача.

Прим. переводчика: я сомневаюсь в необходимости перевода названия принципа, но как один из вариантов предлагаю — «проси, а не спрашивай»
Придерживаетесь ли вы принципа «Tell Don't Ask»?

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Метки:
  • +5
  • 10,2k
  • 9
Поделиться публикацией
Похожие публикации
Комментарии 9
  • +1
    Мне кажется «роботы» лучше описали этот принцип: robots.thoughtbot.com/post/27572137956/tell-dont-ask
    • 0
      Пока не видел ни одного места где бы он был лучше описан чем на прагпроге — pragprog.com/articles/tell-dont-ask
      Там сразу LoD и CQS описаны как неотделимые понятия.
    • +2
      Я нахожу такой принцип полезным, но не в отношении простых объектов, а в отношении более сложных единиц. Если применять принцип «Tell Don't Ask» повсеместно, то у объектов окажется слишком много ответственностей.

      Как правило, у меня есть объект-источник данных, несколько объектов — обработчиков, и, возможно, фасад, который все это скрывает.
      • 0
        Я не понимаю как вообще можно не использовать в ООП этот принцип.
        Если его не использовать то вместо классов и объектов вы пользуетесь просто структурами данных.
        • 0
          Я думаю его все используют, вопрос только в осознанности и в мере. Если осознанности не будет, то вы например не сможете принять решение о рефакторинге классов для того чтобы применить его, вы напишете как проще, и позже ощутите последствия. А осознавая принцип вы сможете понять что вместо
          if condition do возможно придётся пересмотреть ответственности, пошевелить код слегка и сделать только do

          • 0
            Отхождения от этого принципа все-таки возможно. Когда появляется еще одна задача при которой нужно разработать новый код использующий тот же набор данных что и в коде существующего класса. Тогда нужно оценить объем этих данных и если их достаточно много, то логично вынести в некий storage чем писать у существующего множество getBlahBlahBlah(). Тогда-то и появляется Данные отдельно Алгоритмы отдельно, просто потому что сработал другой более важный принцип «Не повторяйся»
          • 0
            Все-таки, «говори, а не спрашивай»
            • 0
              Скорее уж «требуй».

              Но имхо переводить вообще не стоит, фразу из трех предложение освоит даже гугл, а тут дураков вроде не держат
              • –1
                Автор перевода, к сожалению, не осилил.

                И не «требуй», а именно «говори».

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.