3

So I'm coding a way to send events to multiple clients, and then having the clients decide how they want to handle it. I'll exclude the bits that don't lend themselves to explaining the situation.

class Event_Beacon

    def add_event_eater( self, ee ):
        self.event_eaters.add( ee )

    def broadcast_event( self, e ):
        for e in self.event_eaters:
            e.receive_event( e )

Now, with the above, I can create an instance of an Event_Beacon and pass it around. I'm thinking I should stop future me from possibly abusing all that access to the Event_Beacon.

For example, say, I have an Event_Maker. It makes sense for this Event_Maker to have access to the broadcast_event method, but not really add_event_eater. If I just passed it the event beacon instance, I could on some future extension of this particular event maker, haphazardly hack in an add_event_eater inside the event maker.

So, is it good practice to create a limiting interface so that I only give another object exactly what it needs and nothing more? Something like:

class Event_Beacon_Broadcast_Remote

    def __init__( self, event_beacon ):
        self.beacon = event_beacon

    def broadcast_event( self, e ):
        self.beacon.broadcast_event( e )

    # note the lack of add_event_eater in this interface
  • 2
    Yes. It is a good and quite common practice. – Andy Aug 27 '16 at 7:34
4

It is a good idea if you really have the explicit requirement for two different interfaces. That is typically the case when you have to stop others from possibly abusing your existing interface, and you are designing a reusable component or library which needs to provide different access from outside of the component than from inside.

However, creating such interfaces "just in case", for some hypothetical (or superstitous) scenario is a violation of the YAGNI principle, it will only add unnecessary, boilerplate code which makes your software harder to be maintained and evolved.

(For example, for you or your team it may be mostly sufficient to add a comment like "do not use remotely" above the add_event_eater method.)

You have to decide by yourself if in the shown situation to stop future you from abusing the interface falls into the first or the second category. It can be the one or the other, but one has to know the use cases and requirements of your system, the clients of the API and the environment to make a decision, so that is nothing we can decide for you.

4

This is a good enough idea it was given its own name, called the Interface Segregation Principle. It's the 'I' in the SOLID principles. I would caution you against thinking of program designs as some sort of security system against abusive and inept future maintainers, though. An attitude of trying to make things as easy as possible for future maintainers is much better. Segregating your interfaces does this by avoiding introducing unnecessary dependencies that have a maintenance cost but no benefit.

  • Wondering, doesn't the ISP not require interfaces to be split up into disjoint parts? Surely the OP could have done this for his scenario. – Doc Brown Aug 28 '16 at 6:44
  • Ah, yeah, by "stop future me", I intended to convey saving myself future headache by limiting what I could possibly do with what a caller gave me; though it could have been worded in a less aggressive manner. – user2738698 Aug 28 '16 at 10:57
  • No @DocBrown, the ISP itself doesn't requires the interfaces be disjoint, although other principles such as DRY strongly recommend it. – Karl Bielefeldt Aug 28 '16 at 16:13
0

I'm going to say no. It is a good idea to split interfaces into groups of responsiblity. If Event Publishing is seperate from Event Listening then yes, you should make two interfaces.

But you seem to be taking a step further and using them as a form of access rights.

The problem with this is that the rights a consuming object needs are not defined by the consumed class. In order to provide for all possible usages you would be forced to make an interface for every combination of methods on the object.

With only the two methods that's three interfaces, publish, listen and both and it seems like logical areas of responsiblity. But if you have ten methods its 3 million possible access combinations. Having an interface for each would be ridiculous

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.