10

In the following code, is it really bad practice for updateWithContex to return the same object it took as a parameter?

class SomeClass{
   Foo updateWithContex(Foo foo){
       foo.setAppId(i);
       foo.setXId(index);
       //.....
       return foo;
   }
}

class Foo{

    public void setAppId(int appId)
    {
       //
    }
    public void setXId(int appId)
    {
        //
    }
    public void changeState(X x)
    {
       //
    }
}

In C++ , I have seen code like this:

 BigObject&
   fastTransform( BigObject& myBO )
   {
      // When entering fastTransform(), myBO is the same object as the function
      // argument provided by the user. -> No copy-constructor is executed.
      // Transform myBO in some way
      return myBO;   // Transformed myBO is returned to the user.
   }

Is this also wrong?

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
yadab
  • 2,063
  • 1
  • 16
  • 24
  • 2
    Method chaining is a bit different, you return a reference to the object the method was called on, not to the object that was passed as parameter like in this case. – buc Jan 26 '12 at 08:25
  • @buc: True, good point. I was too quick, then – Lukas Eder Jan 26 '12 at 08:32

4 Answers4

13

Returning an object will suggest to users of your API that the passed in object will not be changed and a new modified object returned instead. To make it clear that this is not the case I would suggest changing the return type to void.

Kevin Caravaggio
  • 720
  • 5
  • 19
Jörn Horstmann
  • 33,639
  • 11
  • 75
  • 118
2

Your code should look like this:

class SomeClass{
   void updateWithContex(Foo foo){
       foo.setAppId(i);
       foo.setXId(index);
       //.....
   }
}

It is bad practice, because you pass the reference to the foo object, so you can change it in updateWithContex method without returning it back the method. Once more, remember that you work always with reference with Java. And fore sure, there is no way how to do it elsewhere - it is going to be always a reference to an object. Java has nothing like this: fastTransform( BigObject& myBO ).

Ondrej Kvasnovsky
  • 4,592
  • 3
  • 30
  • 40
  • Fwiw, I would expect that updateWithContext is private, and to this extent the return type is not super-important. If you have public methods that modify the internal state of Foo, I'd declare these as void members of Foo. – Savino Sguera Jan 26 '12 at 08:30
  • I know how Java reference works, that is why I have supplied C++ refs to clarify the need. My question is: Why it is wrong to return Same Foo. When we program with assembly the same registry changes and pushed back, why not in Java? – yadab Jan 26 '12 at 08:39
  • 1
    @yadab - because it is confusing and it might cause a defects in your code. Imagine you could write something like this: Foo updateWithContex(Foo foo){ foo.setAppId(i); return new Foo(); } – Ondrej Kvasnovsky Jan 26 '12 at 08:45
2

I don't see anything wrong, it's a matter of API design. With the code you have posted you can do something like

someClass.updateWithContext(new Foo()).changeState(x);

instead of

Foo foo = new Foo();
someClass.updateWithContext(foo);
foo.changeState(x);

The first code snippet is a better example of fluent interface than the second one.

frm
  • 3,346
  • 1
  • 21
  • 21
  • Thanks! But my case is slightly different than what you replied for(method chaining is not my problem). – yadab Jan 26 '12 at 08:32
1

Output Parameters in Java some objects are mutable some immutable. The thread safety of such methods is doubtful as well. It can be done but yes it is usually considered not a good thing and google for output java paramters too. Hope this helps.

Community
  • 1
  • 1
Sergey Benner
  • 4,421
  • 2
  • 22
  • 29