Когда имеет смысл вернуть эту ссылку? - PullRequest
2 голосов
/ 24 февраля 2009

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

  1. ( mmyers ) при реализации плавных интерфейсов , например

    public class X
    {
      ...
      public X enableValidation()
      {
        setValidation(true);
        return this;
      }
      ...
    }
    
  2. ( Джон Скит ) для преобразования личности , например

    public class X
    {
      ...
      public X toX()
      {
        return this;
      }
      ...
    }
    
  3. ( Dave Ray ), реализующий метод clone() или copy() для неизменяемого объекта , например,

    @Immutable
    public class X
    {
      ...
      public X copy()
      {
        return this;
      }
      ...
    }
    

Существуют ли другие полезные сценарии на объектно-ориентированном языке, в которых вы бы вернули this или self из метода?

Ответы [ 6 ]

4 голосов
/ 24 февраля 2009

Если вы создаете цепочки операций (однако это может быть не очень OOP'ish - Закон Деметры и т. Д.).

Пример (не то, чтобы это имело большой смысл):

public class X 
{
   public X Add(int i) 
   { 
      this.Value += i; 
      return this;
   }

   public X Subtract(int i) 
   {
      this.Value -= i;
      return this;
   }

   public int Value 
   {
      get;
      set;
   }
}

new X().Add(4).Subtract(5).Value;
2 голосов
/ 24 февраля 2009

Любая реализация метода clone () или copy () для неизменяемого объекта.

2 голосов
/ 24 февраля 2009

String.toString ():)

На более серьезной ноте, есть похожие сценарии "конвертировать в [x]", где можно просто вернуть "this" ... но я не могу вспомнить очень много других ситуаций.

0 голосов
/ 24 февраля 2009

Возьмите следующую реализацию.

public interface Monitorable {
   public Statistics getStatistics();
}

public interface MonitorManager {
   public Monitorable getMonitorable();
}

class MonitorableService implements Monitorable, MonitorManager {
   public Monitorable getMonitorable() {
      return this;
   }
}

// Meanwhile somwhere else...
MonitorManager manager = getMonitorManagerFromSomewhere();
Monitorable monitorable = manager.getMonitorable();

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

Здесь мне не нужно знать, что MonitorManager реализуется классом Application. Также мне не нужно знать, что приложение Monitorable реализуется приложением.

Здесь полиморфизм используется для инкапсуляции деталей реализации Application. Который не публичный класс. Это очень распространенная модель, и ее можно увидеть в самых разных проектах.

0 голосов
/ 24 февраля 2009

Быстрое добавление, когда дело доходит до свободных интерфейсов:

Как упомянуто в этой статье "Простой пример свободного интерфейса" (в конце комментариев):

Вы попадете в кирпич, когда будет использовать наследование вместе с текущими интерфейсами, потому что:

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

альтернативный текст http://withasmiletomeltathousandhearts.files.wordpress.com/2009/02/fluent_interfaces_order_class_hierarchy.jpg?w=300&h=255

В этой статье о более надежном шаблоне для сложной (и все же свободно) иерархии классов , "this" используется для возврата экземпляра базового класса " Строитель ", тогда как Строитель для конкретных классов использует литье.

0 голосов
/ 24 февраля 2009

C ++ делает это все время, чтобы разрешить каскадные операторы.

например, оператор << всегда возвращает себя (ostream), чтобы вы могли каскадировать вызовы таким образом: </p>


std::cout << "call 1" << "call2" << std::endl;

Единственный язык, который, как мне кажется, этот каскадный эффект популярен - это C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...