tags:

views:

189

answers:

4

Why setters are bad in interfaces if we are speaking about domain objects?

Clarification:

I have a domain object which stores in db. It has several fields which is very costly to set. I.e.

class JurasicPark {

  private long area;

  ...other fields ...

  getters and setters

  ....

  private Collection<Dinosaur> dinosaurs;
  private Collection<ExoticTree> flora;

  public Collection<Dinosaur> getDinosaurus(){
      ...
  }

  public Collection<ExoticTree> getFlora(){
      ...
  }


}

Fields dinosaurs and flora are very costly to init and set. But in many cases I don't need this fields to be set every time.

The problem is that if I return to user instance of JurasicPark class with dinosaurs or flora don't initialized it fill lead either to NPE or some expection I throw myself. I don't want to make api user to think about this and to remember which fields may be not set.

So to solve this I thought about creating two interfaces IJurasicPark and IFullJurasicPark the first will declare all access methods to simple fields, former will declare access methods to the flora and dinosaurs fields.

   interface IFullJurasicPark extends IJurasicPark

    class IJurasicPark implements IFullJurasicPark

In this approach IJurasicPark interface will contain getters and setters, so I actually asks is this design is bad one?

I also don't want to implement it in hibernate style with LazyInit exceptions.

+11  A: 
Péter Török
I think this is coming from the observation that "blindly autogenerating getters+setters for all properties of a class" is relatively common, and thus lots of classes have more setters than they should have.
Michael Borgwardt
@Michael, it is sadly true (witness 90% of the classes in our legacy project :-((( ) But why blame poor setters for the harm done by careless / inept developers?
Péter Török
A: 

Honestly, I Don't know very much about what this, but what they taught me at school was that u can use a interface as a shell around a business class. So the object that's talking to the interface has no knowledge about the actual object behind it. Therefore u maybe dont want to make setters as they would make it possible to modify and see the contents of the actual object.

Instead I was told to use methods to modify the object.

Somebody can clarify what I am saying or am I mixing things up now?

what I am talking about in code translates as:

Interface IBoard = new ActualBoard();
Emerion
+1  A: 

In general, setters are not a problem, and are very useful to include in interfaces, there are a couple of cases that they aren't good. But both cases are pretty common sense anyway.

Basically, if the class (or the class member) is immutable, it doesn't make sense to have a set method. Péter was making mention of this.

The other time is when it doesn't make sense in your abstraction. For example, let's say you had a Car class (yes, this is a car analogy) with an int speed class member in a racing simulation/game. Realistically, one can accelerate and decelerate, one can not instantly SET their speed, so revealing a setSpeed method doesn't make sense.

Having said that, a setSpeed method can still be useful for debugging purposes, or internal operation. For example, the interior of the class could be written.

private void setSpeed(int newSpeed) {
    if(newSpeed < 0)
        error();
    speed = newSpeed;
}

public void accelerate() {
    setSpeed(getSpeed() + 1);
}

Notice the set method is private, while your acceleration function is public. The setSpeed here is essentially to avoid code duplication.

Roadrunner-EX
A: 

I would argue that your Interface shouldn't contain methods to modify properties it doesn't know it has.

This appears to be Java, which means that you can't declare private/protected properties in your interface; it's simply not allowed. As a result, you're tying the interface to the implementation (using specific properties), which could be considered bad practice. Generally, it's one I try to steer away from.

EricBoersma