Interface/Impl confusion

I was just restructuring some of my code and I decided to extract interfaces out of some concrete

classes. I'm not really expecting to have multiple impls for them, but I did it to reinforce thinking in interfaces and to have a good view over the class without having to look at implemntation details.

Here's a Channel-interface I extracted (an abstraction to IRC-channel):

publicinterface Channel{

publicvoid addChannelListener(ChannelListener listener);

publicvoid removeChannelListener(ChannelListener listener);

publicvoid send(String message);

publicvoid rejoin();

publicvoid leave();

publicvoid say(String text);

publicvoid ban(String nickOrAddress);

publicvoid unban(String nickOrAddress);

publicvoid kick(String nick);

publicvoid kick(String nick, String reason);

publicvoid invite(String nick);

publicvoid setInviteOnly(boolean enabled);

publicvoid setTopic(String topic);

public Server getServer();

public String getName();

public String getKey();

public String getTopic();

publicint getUserCount();

public User[] getUsers();

publicboolean isConnected();

publicboolean containsNick(String nick);

}

Note that this is still an incomplete implementation and there'll be some more of these methods.

Now, earlier I had a concrete Channel-class and it also had methods like this:

publicfinalvoid topicChanged(Message msg){...}

publicfinalvoid messageReceived(Message msg){...}

publicfinalvoid modeChanged(Message msg){...}

publicfinalvoid nickChanged(Message msg){...}

publicfinalvoid userJoined(Message msg){...}

I decided to leave them out of the public interface as they don't really belong there,

since they are called only by the Server-class. The Server-class contains a list of Channel-objects.

It is also the only class that creates new Channel-objects.

So, only the Server-class calls the above methods of it's Channel-objects, when the server receives new messages (and determines they're channel-messages).

I also extracted an interface for the Server, and the ServerImpl now casts the Channel-interfaces to ChannelImpls in some places, to be able to call the above leftover methods.

Is this a bad idea? Does this break the 'Liskov substitution principle'? Do you have any better ideas? Maybe the Channel-class should do 'more work' itself?

I personally don't feel it's that bad but i still get kind of dirty feeling of doing it this way.

[4766 byte] By [finalfrontiera] at [2007-11-26 22:01:14]
# 1

So th eChannel interface is the public interface for all others present

in the system but your server needs a bit more functionality. Why not

define another interface:interface ServerChannel extends Channel {

// server specific methods here

}

and your ChannelImpl class:public class ChannelImpl implements ServerChannel { ... }

Now the server treats these ChannelImpl objects as ServerChannels,

while the rest of the world simply treats these objects as Channels.

btw, you can build a Factory that builds the appropriate objects for the

appropriate callers, e.g. a package scoped method for the server

(which needs to be in the same package) and a public method for the

rest of the world. The first object would return ServerChannels while

the second method (the public one) would return Channels:[code

public class ChannelFactory {

ServerChannel makeServerChannel() { ... }

public Channel makeChannel() { return makeServerChannel(); }

...

}[/code]

kind regards,

Jos

JosAHa at 2007-7-10 10:36:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 2
Hi JosAH, that was quite nice and elegant way to do it. Thanks for your help.
finalfrontiera at 2007-7-10 10:36:46 > top of Java-index,Other Topics,Patterns & OO Design...
# 3
> Hi JosAH, that was quite nice and elegant way to do it. Thanks for your help.Your welcome of course and sorry for the [code] ... [/code] typo inmy previous reply (fingers got stuck again ;-)kind regards,Jos
JosAHa at 2007-7-10 10:36:46 > top of Java-index,Other Topics,Patterns & OO Design...