3

I have two chat rooms, one has administration behaviour, and one doesn't. I have factored out all of the common code into a base chat room, but the AdministerChatroom behaviour I have pulled out into an interface called IAdministrable and it sits on the base chatroom class.

My issue is that because the interface is on the base class, which allows for the behaviour to polymorphic, the NonAdministratableChatroom chatroom class must implement that behaviour even though it will do nothing.

I have seen some developers put the interface on only one subclass: the class that has the behaviour, in this case the AdministerChatroom method, and when a chatroom is being used, they simply check the existence of the the IAdministrable interface, something like if(Chatroom is IAdministrable){ // do something }, which seems like a violation of the "tell don't ask" principle.

I seem to have two choices: I stick to the polymorphic strategy pattern, or I test the instance for an interface; the former seems preferable but I am wondering if there are any other options?

The code for the classes is as follows:

public interface IAdministrable
{
    void AdministerChatroom();
}

public abstract class BaseChatRoom : IAdministrable
{
    public void Close()
    {
    }

    public abstract void AdministerChatroom();
}

public class AdministrableChatroom : BaseChatRoom
{
    private readonly Administrator _administrator;

    public AdministrableChatroom(Administrator administrator)
    {
        _administrator = administrator;
    }

    public override void AdministerChatroom()
    {
        _administrator.DoSomethingSpecial();
    }
}

public class NonAdministratableChatroom : BaseChatRoom
{
    public override void AdministerChatroom()
    {
        // do nothing as this is not administrable
    }
}

public class Participant
{

}

public class Administrator : Participant
{
    public void DoSomethingSpecial()
    {
        // implement something special here
    }
}

migrated from codereview.stackexchange.com Sep 1 '14 at 4:20

This question came from our site for peer programmer code reviews.

7

It annoys me that object-oriented design education focuses almost exclusively on designing object hierarchies and almost completely neglects the structure of the other, often larger, side of object-oriented programs: the calling code.

The answer is to put the interface on only one subclass, and structure the calling code so all the calling code either doesn't care which subclass it is acting against, or always already knows it implements your administrable interface.

In other words, at some point some of your code will want to call AdministerChatroom. That should either be from within another method of the AdministrableChatroom object, or from a collection or event handler somewhere that only has a reference to an IAdministrable. If your calling code isn't structured that way, it needs refactoring. If you need help with the refactoring, you need to post more details of your calling code.

  • 1
    +1, since I think this is most probably adequate for the case of the OP. Actually, this may imply to have a "BaseChatRoom" somewhere beeing tested (at least once in the example) if it is of the given interface type, as the OP stated. And when there are more than two subclasses, or the types of chatrooms will have to be extended, this can become hard to maintain. – Doc Brown Sep 1 '14 at 6:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.