Tuesday, April 26, 2005

Object Oriented Question

Lets say I have some interfaces which make up a framework:

public interface Gum {
public String getFlavor();
}

public interface Package {
public Gum getGum();
}

public interface

There are no setter methods because the values may be set/retrieved different ways.

And I have a particular implementation

public class GumImpl implements Gum{
private String flavor;
public String getFlavor() { return this.flavor; }
public void setFlavor(String flavor) { this.flavor = flavor; }
}


public class PackageImpl implements Package{
private GumImpl gum;
public GumImpl getGum(){return this.gum;}
public void setGum(GumImpl gum){ this.gum = gum; }
}


First of all, notice that I am returning GumImpl from my PackageImpl.getGum and the interface defines that Package.getGum() should return a Gum type. To me, this seems appropriate because that classes that interact with the implementation shouldn't have to deal/cast to the from the interface to the implementation.

Does anyone have an opinion if changing the method signature to return a subclass like this is appropriate?

I am having problems using various tools with this approach such as Spring and Netbeans. Spring will complain that the PackageImpl is read-only.

9 comments:

Anonymous said...

I believe the idea of having interface is to hide the implementations from the clients. This defeats the purpose of interface.

Anonymous said...

the whole idea of separating interfaces from implementations is to *never* let the client see any of the specific classes which implement the interfaces.
with your approach, it would never be possible to change the interface's implementation without breaking client code.
if you feel the need to cast the returned reference to the implementation class's type, you obviously forgot to put something into the interface - it should be sufficient for the client to know the type of the interface only, no need to know about concrete ...Impl-types.
the only place where implementation class's names tend to show up in client code is at the place where the instance is created (i.e. after the "new"-keyword), but even that is commonly avoided by using factory methods or factory classes to create instances and therefore encapsulating the knowledge of concrete implementation types in there.
take a look at java frameworks like jdbc, jaxp, jndi etc., where all the api's used by client code are interfaces or base types and the concrete implementations provided by some service provider (i.e. anyone but sun itself) are commonly configured declaratively in system properties, xml-config files or the like, so that the name of an implementing class's type *never* shows up in client code and can moreover be changed declaratively without touching any client code.

Taylor said...

Your problem materializes you are mixing distinct behaviors -- mutable and non mutable -- in your interface and implementation definitions. Your Gum interface is defining a non-mutable type, yet your GumImpl is mutable.

Recast your GumImpl as an immutable class to match your immutable interface type definition and you won't have these problems. In other words:

public final class GumImpl implements Gum
{
private final String flavor;

public GumImpl(String flavor)
{
this.flavor = flavor;
}
... (implement getter, and no setter)
}


On the other hand, if "Gum" should be mutable (in the real world, gum never is mutable in the classic sense, if I buy a pack of gum, the flavors cannot be magically changed by any normal real world operation) then your interface should reflect that and have a setter method for it (and then of course GumImpl will have a setter method and the clients of your class will never need to see a GumImpl).

For more on immutable types, and why you should prefer them, read Bloch's Effective Java.

Anonymous said...

Updawssap, clomid online fefearyjaky, [url=http://www.webjam.com/clomidonline]buy clomid[/url] Weigneemaibre
23

Anonymous said...

chararorylarp, buy zyrtec, Carardykats, [url=http://www.webjam.com/zyrteconline]zyrtec[/url], Glaccerve

Anonymous said...

TexanyThync, viagra tramadol zithromax carisoprodol buy cialis, piluerryMer

Anonymous said...

Verduekssem, propecia online, spancenus, [url=http://virb.com/propeciaonline]propecia[/url]

Anonymous said...

estaliBriesty, tramadol, bealiaVet, buy cheap tramadol, Hifavamom, order tramadol nex day delivery, dofafforp, tramadol online, MatBultapetle

Anonymous said...

estaliBriesty, tramadol, bealiaVet, buy cheap tramadol, Hifavamom, order tramadol nex day delivery, dofafforp, byu tramadol online, MatBultapetle