I'm having a discussion in my company on how to structure a student enrollment application we are doing.

We have an SOAP-Service for sending Emails. This Service is in charge of sending, and logging emails send from our different applications.(lets call it EmailService)

Then we have a SOAP- service that handles all needed logic for the enrollment of a student.(lets call it EnrollmentService)

Then we have a client application (UI) that has some small business rules and calls the formerly mentioned Soap Services.

The SW-architecture discussion we have is as follows:

I would like the client application to call the EmailService when needed and let the EnrollmentService only handle thinks of the enrollment.

My fellow developers would like to only include the the EnrollmentService in the client application, add a SendEmail() method in the EnrollmentService and let this EnrollmentService include the EmailService and call the needed methods.

I kind of think that this violates the "separation of concerns" paradigma...

My argument:

What if suddenly another client application that uses the EnrollmentService would choose to use a SMS-Service instead of the EmailService... then we would need to extend the EnrollmentService with a SendSMS() method. Suddenly the EnrollmentService would have to know of may different communication services.

My fellow developers say: "we'll never need anything else than E-Mail", and "we will not need another client app for this". I say: "you never know..."

Can someone tell me which approach might be better

Thanks a lot

  • No one will ever need more than 640K, to paraphrase a comment attributed to Bill Gates. "Never" is a bad way to design a system, but a good way to ensure future work. – Phil N DeBlanc Oct 19 '18 at 9:41
  • When (in what scenario) does an email get sent? And to whom is it sent? Is that purely the decision of the user, or is it primarily based on some standard sequence of enrollment events? – StarTrekRedneck Oct 19 '18 at 12:34
  • @StarTrekRedneck it is on some standart sequence of the enrollment process. For example after the student delivered all needed paperwork, or after he gets approved to visit the course. But the EmailService is used as such in many other applications. It's like a queue for emails for applications of our school – CodeHacker Oct 19 '18 at 12:43

If the user is making the direct decision to send the email, then the client app is definitely the place for it.

However, if as your comment suggests, the sending of the email is the result of some set sequence of events like when a student is approved for a course, then, in a pinch, I may have the logic of when to "NotifyStudentOfApproval()" in the Enrollment service, but this would absolutely wrap a call to the SendEmail service and not be built against any SendEmail dll's. Also, the call would be well-wrapped in try-catch so that any errors sending the email wouldn't prevent the approval process from succeeding.

But doing this still conceptually couples that event to an email within your service. If "when the notification is sent" changes, or something about how that email is constructed changes, or if the mechanism of communication changes (like you speculated), then the Enrollment service is forced to change. Also, what happens when SendEmail is down or returns an error? As I mentioned, you don't want that to bring Enrollment to hault. But does that mean students would not get notified? I don't like any of that.

So really, I would recommend considering using pub-sub style (and reliable) messaging to inform a separate service that an approval has happened. Perhaps this service is very small and single-purpose: NotifyStudentOfApproval (depends on what all else may be very similar in that line or responsibility). The Enrollment service would publish events, like "StudentApprovedForCourse". The other service would subscribe to those events, and then take the necessary action of notifying the student in whatever way is appropriate, like an email. And it would call the email service. So when one of those above "if" scenarios occur, then the Enrollment service is unaffected. Changes are limited to the NotifyStudentOfApproval service and deployment is limited to that as well. Also, with queued messaging, you can usually deploy anytime without concern about students failing to get notified.

Breaking things up (a bit, not too much) like this can really sooth the pain of making a change "over here" and affecting everything. Also, assuming the messaging is queued as it should be, it makes system downtime far less impactful. In this example, if the SendEmail service goes down for a while, or NotifyStudentOfApproval is being deployed, that's fine. When either comes back up, they will process all the notifications that backed up in their "inbox" of messages. This is so much better than having things break because anything is ultimately dependent on everything. "I can't approve the student for the course because the email system is down." etc.

| improve this answer | |
  • Hello. Thanks for the thoughts- Our Email service is exactly for that.. Handling Email errors.. retrying. informing responsible people if errors occurred, etc.. That is why we never send form any service nor app an email directly... it is our policy to send it through the service. The idea of a pub/sub is really worth a thought. Right now, if the email fails, my App doesn't care... because I now the service has all information needed to inform the responsible people. (we have to register that be able to instantiate an instance of the service – CodeHacker Oct 19 '18 at 14:02
  • I think you've got a good portion of the issue solved, then. I would still go for the separate service to encapsulate the logic about reacting to certain Enrollment events. Embedding the logic to handle the events within the Enrollment service would probably bloat it. It sounds like it's doing plenty and it sounds like you sense that. Also, it may be that a couple events (or more and in any order) may have to happen to warrant a notification, and a separate service will provide liberty to maneuver in that manner. – StarTrekRedneck Oct 19 '18 at 14:15

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.