I have objects which implement the interface BroadcastInterface
, which represents a message that is to be broadcast to all users of a particular group. It has a setter and getter method for the Subject
and Body
properties, and an addRecipientRole()
method, which takes a given role and finds the contact token (e.g., an email address) for each user in the role and stores it. It then has a getContactTokens()
method.
BroadcastInterface
objects are passed to an object that implements BroadcasterInterface
. These objects are responsible for broadcasting a passed BroadcastInterface
object. For example, an EmailBroadcaster
implementation of the BroadcasterInterface
will take EmailBroadcast
objects and use the mailer services to email them out.
Now, depending on what BroadcasterInterface
implementation is used to broadcast, a different implementation of BroadcastInterface
is used by client code. The Single Responsibility Principle seems to suggest that I should have a separate BroadcastFactory
object, for creating BroadcastInterface
objects, depending on what BroadcasterInterface
implementation is used, as creating the BroadcastInterface
object is a different responsibility to broadcasting them.
But the class used for creating BroadcastInterface
objects depends on what implementation of BroadcasterInterface
is used to broadcast them. I think, because the knowledge of what method is used to send the broadcasts should only be configured once, the BroadcasterInterface
object should be responsible for providing new BroadcastInterface
objects.
Does the responsibility of "creating and broadcasting objects that implement the BroadcastInterface
interface" violate the Single Responsibility Principle?
(Because the contact token for sending the broadcast out to the users will differ depending on the way it is broadcasted, I need different broadcast classes—though client code will not be able to tell the difference.)
2 Answers 2
I don't know PHP, but OO-wise you have a problem here. If something implements the BroadcastInterface, it should be good for anything that expects a BroadcastInterface
instance.
First suggestion: create A, B, C, ... versions of each BroadcastInterface and BroadcasterInterface (BroadcastIntefaceA, BIB, BIC, and BerIA, BerIB, and BerIC.) These can extend the original interfaces, but they will keep your relationships straight; the correct BI will go with the correct BerI, or, in most languages I know, you'll get a compiler error. Otherwise, things will be hopelessly confused instead of merely confused. Probably you want each BerI extention to produce the appropriate BI extention.
Second suggestion: skip the extensions. Take the code in the BI implementations that make them behave differently and put it in the BerI implementors. Now you don't have to worry about it at all. And the interfaces tell all the story that anybody using them needs to know.
I don't know PHP or your program well enough to say which, if either, solution is the best. (If I were to take charge of your code, I'd do anything to make the second suggestion work, though.) But interfaces need to tell all the story anyone needs to know. The code using the interface should not know anything more about the implementor than what is in the interface. The implementor should know nothing about the user beyond what it picks up through the interface.
-
1I think the problem is that what the Broadcaster needs from the Broadcast depends on how the Broadcaster works. For example, if it broadcasts using email, the Broadcast needs to contain an array of all email addresses to send it to. If the Broadcaster were to use SMS, it would need telephone numbers. I think that sort of data needs to be encapsulated in the Broadcaster - not the Broadcast. The Broadcast should only really consist of a subject, message and array of user roles to send to. The Broadcaster then does the work of getting the data it needs.Lewis Bassett– Lewis Bassett05/14/2012 06:32:49Commented May 14, 2012 at 6:32
If you have no code that works against a BroadcastInterface directly there is no point in having it. Even if you have multiple implementations of it, you use it more as a sort of template then as an abstraction.
So an EmailBroadcaster should able to work with any implementation of BroadcastInterface.
In this case I would consider merging BroadcasterInterface with BroadcastInterface. Put behavior with the data.
Explore related questions
See similar questions with these tags.