Friday, April 8, 2011

When does it make sense to return this-reference?

Currently I can think of only three good reasons to return this in a (public) method, namely:

  1. (mmyers) when implementing fluent interfaces, e.g.

    public class X
    {
      ...
      public X enableValidation()
      {
        setValidation(true);
        return this;
      }
      ...
    }
    
  2. (Jon Skeet) for identity conversions, e.g.

    public class X
    {
      ...
      public X toX()
      {
        return this;
      }
      ...
    }
    
  3. (Dave Ray) implementing a clone() or copy() method on an immutable object, e.g.

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

Are there any other useful scenarios in an object-oriented language in which you would return this or self from a method?

From stackoverflow
  • String.toString() :)

    On a more serious note, there are similar "convert to [x]" scenarios where it's okay to just return "this"... but I can't think of very many other situations.

    eljenso : Ok, good answer, identity conversion.
  • Any implementation of a clone() or copy() method on an immutable object.

    eljenso : Agree, good answer.
  • If you are creating chaining operations (however this might not be very OOP'ish - Law of Demeter, etc).

    Example (not that it makes a lot of sense):

    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;
    
    eljenso : Fluent interface, already covered in the question. Still, good that you agree that this is a valid and useful reason for returning this.
    veggerby : Ahh, sorry ;) Note to self: read complete question next time
  • C++ does this all the time to allow cascading operators.

    for example the << operator always returns itself (ostream) so that you can cascade the calls in such a way:

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

    The only language which I believe this cascading effect is popular is C++.

    eljenso : I guess this falls in the category of fluent interfaces (already covered in the question) which is more common than I thought.
  • Quick addition when it comes to fluent interfaces:

    As mentioned in this "A simple example of a fluent interface" article (at the end of the comments), :

    You'll hit a brick when using inheritance along with fluent interfaces because:

    • using polymorphic methods break your call chains and
    • you definitely don't want to make your interfaces non-fluent by using ugly casting and parenthesis where they are not needed or by doing lots of un-useful overrides in the children that do the casting

    alt text

    In this article about a more robust pattern for complex (and yet fluent) hierarchy of classes , "this" is used to return the instance of the base class "Builder", whereas Builder for concrete classes uses casting.

    VonC : I know, not *exactly* an answer to your question, but I find this pattern for "fluent" hierarchy interesting.
  • Take the following implementation.

    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();
    

    I admit this is rather contrived, but the overal pattern/message should be clear.

    Here I do not need to know the MonitorManager is implemented by the Application class. Nor do I need to know that Monitorable is implemented by Application.

    Here polymorphism is used to encapsulate the implementation details of Application. Which is not a public class. This is a very common pattern, and can be seen in a wide variety of projects.

    eljenso : First of all, thanks for responding. I can read your code more clearly now, but I still don't get some things. Where is the Application class? Why is the Monitor interface declared but not used? Is the only function of MonitorManager to return a Monitorable?
    eljenso : I think that what you express here can be solved by using the correct types. An instance of MonitorableService can be declared as Monitorable or MonitorManager or MonitorableService (which includes both) depending on the context.
    ng : Yes, the contract of MonitorManager has been achieved with a single object, although several are in play. The implementation details are hidden from the user, this could be implemented in other ways, however there is often very useful to realise the contract in this way, as many frameworks do.
    eljenso : Again you say that this is a common pattern. You've even said that it's a critical requirement of most OO systems. So maybe you could show me one or two projects where this pattern is used?
    ng : Well I said the examples I gave were fundamental, this pattern was included with passing an object to a method using "this" as you may remember, a much more useful use of this than "this.field". I think the pattern here is obvious, and useful. You will see examples it in many frameworks.

0 comments:

Post a Comment