3

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.

Vladimir
  • 12,753
  • 19
  • 62
  • 77
  • Duplicate: [Java: Are Getters and Setters evil?](http://stackoverflow.com/questions/565095/java-are-getters-and-setters-evil), [Getters and Setters are bad OO design?](http://stackoverflow.com/questions/2747721/getters-and-setters-are-bad-oo-design), [Allen Holub wrote “You should never use get/set functions”, is he correct?](http://stackoverflow.com/questions/996179/allen-holub-wrote-you-should-never-use-get-set-functions-is-he-correct) – gnovice Sep 28 '10 at 13:54
  • @gnovice, I am not quite sure whether this is an exact duplicate (especially after the update) - may be, but without more context it is still hard to tell what this question is exactly about. – Péter Török Sep 28 '10 at 13:59
  • your update is confusing (to me at least). Please try to clarify - explain the context better, give a reference to the source of your question, add an example, ... – Péter Török Sep 28 '10 at 14:06
  • I updated my answer based on your clarification. Note that I noticed your update only by chance; if you want to make sure that answerers get notified about updates, you should post comments to their answers. – Péter Török Sep 29 '10 at 14:26

4 Answers4

10

Who told you that? It is certainly not true in general.

It may be true in some cases, where the property in question should not be modified by external parties. E.g. the interface of an immutable class surely must not contain setters.

It is true that one should think carefully when designing interfaces, instead of blindly autogenerating getters+setters for all properties of a class. But this does not mean setters are always bad.

Update after clarification of question

Your clarification changes the question completely... you could have saved yours and others' time by starting with this question right away. Although no complaints from my part - I got a lot of (undeserved) upvotes :-)

So your problem is initializing / setting costly collection properties in a domain object. My first approach would indeed be lazy load / save, which can be implemented in a lot of different ways depending on the context.

Your post suggests (but does not state explicitly) that the collections in question are fetched from / persisted to a DB. However, you don't mention what persistence solution you use. Neither do you explain why you don't want a "Hibernate style lazy init" - IMHO it is very efficient and easy to use in most cases. If you give us more details on these, we might be able to provide better answers.

The splitting of interfaces you suggest may make sense if a JurassicPark object without dinosaurs and flora makes logical sense and is usable as is. Again, it is difficult to judge this without more context. You seem to be making a design decision based on an implementation detail, which is not a good idea in general.

If you really want to go that way, you shouldn't actually need separate interfaces - just define a JurassicPark (abstract) base class containing the simple members plus their accessor methods, then subclass it with another class which adds the heavyweight fields.

Community
  • 1
  • 1
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 1
    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 Sep 28 '10 at 14:33
  • 1
    @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 Sep 28 '10 at 14:37
1

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
  • 824
  • 11
  • 23
1

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
  • 1,019
  • 1
  • 8
  • 19
-1

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
  • 820
  • 6
  • 13