Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Real Life Single Responsibility Principle

S.O.L.I.D. principles seem to be a hot topic.  The guys over at LosTechies.com explored it last year in March as their topic of the month and did a great job of it. I know when I read blogs I enjoy when different authors post on similar topics.  I find that often the different examples and explanations paint a clearer picture than can be had with only one example.  I'd like to share an area where we use the Single Responsibility Principle (SRP) in our application

Note: The "aha" moment won't be some thrilling display of how we averted some disastrous bug or how we eliminated some thousands of lines of code.  It will be much more subtle but that's ok.  A good design should strive for an element of simplicity.  Great design is asking to hear the answer to a riddle and then thinking, "duh!  of course"  When you hear the answer you realize how "obvious" it was.

Background

In our application we queue all emails to be handled by a different process since sending email is a blocking call which slows your response times (Note to BCL junkies: yes I know there is a SendAsync method).  There are a few instances in our application where we want email to be sent right away and not queued. An example of this would be a confirmation email for a new account or a password reset request.

The Fix

We already had a QueuedEmailService class so adhering to SRP, I built a RealTimeEmailService class whose job, and only job, it is to send the email right away.  Thinking of responsibility driven design, classes:

  • Know things
  • Do things
  • Make decisions

With that in mind I needed another class to make the decision to when to send the email through the RealTimeEmailService or when to use the QueuedEmailService:

(At this point some of you might be reading thinking how easy of a problem this would be to solve and you're quite right.  What I want to point out is not the problem, but how one solves the problem.  Nearly anyone could've gone into the QueuedEmailService and added an if statement and sent emails real-time if that is what is needed, thus ignoring SRP.  By lumping all of the work together you aren't building object oriented software...sorry.  And while you might be okay with that and you're software WILL work, you run the risk of more maintenance issues and modularity problems).

Here's what a quick summary of what I've got:

   1: public QueuedEmailService : IEmailService
   2: {
   3:     public void Send(...)
   4:     {
   5:         // add to some queue
   6:     }
   7: }
   8:  
   9: public RealTimeEmailService : IEmailService
  10: {
  11:     public void Send(...)
  12:     {
  13:         // send right now
  14:     }
  15: }
  16:  
  17: public PriorityBasedEmailService : IEmailService
  18: {
  19:     public void Send(...)
  20:     {
  21:         if (priority == MailPriority.High)
  22:             // send using realtime service
  23:         else
  24:             // send using queued service
  25:     }
  26: }
  27:  
  28:  

I know many people who would look at the code above and think it is possibly overkill.  I would disagree for a few reasons:

  • Each class does only one thing.  If we have a problem with some piece of functionality it is much easier to debug.  Each of the three classes above in their full implementation will fit on your screen without the need for scrolling.  It's quite refreshing.
  • Modular design - since the application only knows that it's dealing with an IEmailService I can easily swap out implementations.  For example, if we decide that we want all emails to be sent real-time, I just change how I've configured Windsor (my IoC container) and it works, because I have a concrete class which sends real-time.  If you were to combine all of your code into one class, you'd have to go back and change your code and go through the pain of deployment.
  • Open-Closed principle - since each of the classes only have only one thing they do, I can more easily say they are closed for modification, reducing the chance that I introduce a bug later on.  If you put this code into one big method, you can change the code to meet your new needs, but each change introduces the possibility of introducing a bug.

There are cases when a design can go overboard, but for the vast majority of cases this simply isn't the case.  I'd rather see a solution where someone has gone too far than what I typically see in classes that do it all, with no clear responsibility.

I hope this helps augment your knowledge of SRP.  If you're still a little fuzzy on SRP and what it is, let me know, I'd love to discuss it with you.


Posted 01-05-2009 2:23 PM by Tim Barcz
Filed under:

[Advertisement]

Comments

Jeremy D. Miller wrote re: Real Life Single Responsibility Principle
on 01-05-2009 3:34 PM

Nice post Tim.

Tuna Toksoz wrote re: Real Life Single Responsibility Principle
on 01-05-2009 3:43 PM

+1 Really nice post. Thanks!

DotNetKicks.com wrote Real Life Single Responsibility Principle
on 01-05-2009 4:03 PM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

Zac wrote re: Real Life Single Responsibility Principle
on 01-05-2009 4:06 PM

Nice post.  I don't currently use SRP but thanks to this post i know exactly what it is and how i would use it.  Good Stuff!

SuperJason wrote re: Real Life Single Responsibility Principle
on 01-05-2009 4:43 PM

"(Note to BCL junkies: yes I know there is a SendAsync method).  There are a few instances in our application where we want email to be sent right away and not queued."

Are you suggesting that SendAsync doesn't send the email immediately? Not a big deal, but it works the same as "Send", but the call itself is asynchronous.

Tim Barcz wrote re: Real Life Single Responsibility Principle
on 01-05-2009 4:48 PM

@SuperJason,

Catching issues around mail and failing is harder with SendAsyn from my experience.  When it's a blocking call and it fails, you know.

Lee Carter wrote re: Real Life Single Responsibility Principle
on 01-05-2009 5:07 PM

First, thanks for re-reminding me of the RDD concepts: Know, Do, Decide - it's a great, and useful, distinction.

Second, I found the "now you might be thinking..." comments kind of annoying, until I realized that, yes, that's exactly what I was thinking. It was useful to get called on it. So...thanks for that, too.

Lance wrote re: Real Life Single Responsibility Principle
on 01-05-2009 5:31 PM

You don't show how these classes are being used.  When do you know whether to use Queued or Realtime if you don't use an if statement?  There's an if statement in the PriorityBasedEmailService which seems like more conditions could be added on later.

SuperJason wrote re: Real Life Single Responsibility Principle
on 01-05-2009 5:32 PM

Ok, I was just trying to clarify what you were saying.

Personally, I avoid SendAsync as well.

Tim Barcz wrote re: Real Life Single Responsibility Principle
on 01-05-2009 5:35 PM

@Lance

The if statement is how I know which one to use.

Three classes, three different responsibilities:

1. QueuedEmailService - queue the message for some other processing

2. RealTimeEmailService - send the mail right now

3. PriorityBasedEmailService - figure out which service to use.

Does that clear it up at all?  Let me know and I'll seek to clarify further.

Lance wrote re: Real Life Single Responsibility Principle
on 01-05-2009 5:50 PM

I'm talking about how consumers would use this class.  How would they know to use one mail service or the other?  If the only difference is the mail priority, I'm not sure why the Queued or Real time services would even need to be exposed to the client since sending it to the PriorityMailBasedService would take care of sending the email without the client needing to worry about the priority which seems to be more agree more with the Law of Demeter.  Forgive me if I am being dense.

Tuna Toksoz wrote re: Real Life Single Responsibility Principle
on 01-05-2009 6:23 PM

@Lance probably IoC would do that, you can configure a specific class to be resolved.

Reflective Perspective - Chris Alcock » The Morning Brew #258 wrote Reflective Perspective - Chris Alcock » The Morning Brew #258
on 01-06-2009 3:52 AM

Pingback from  Reflective Perspective - Chris Alcock  » The Morning Brew #258

Dew Drop - January 6, 2009 | Alvin Ashcraft's Morning Dew wrote Dew Drop - January 6, 2009 | Alvin Ashcraft's Morning Dew
on 01-06-2009 9:27 AM

Pingback from  Dew Drop - January 6, 2009 | Alvin Ashcraft's Morning Dew

Tim Barcz wrote re: Real Life Single Responsibility Principle
on 01-06-2009 9:49 AM

@Lance

Tuna is correct, everything get's stitched together through our use of Windsor (IoC container).  I recognize that this may create some confusion when people say "just use an IoC container" and so I hope to get some concrete examples out there sometime

Scott wrote re: Real Life Single Responsibility Principle
on 01-07-2009 8:29 AM

What happens when you have a second high priority message to send before the previous high priority message send is complete?  Don't the high priority messages need to queue up also?

Not to disagree with how you implemented the solution you decided upon but rather to suggest another solution; Did you consider have multiple queues and a class to pull from the queues based on priority?  Ie. a low priority and high priority queue. Many MTA's use this approach as it is conceivable that many high priority emails will need to be sent at any given time. At that point, you need to work through all the high priority items before returning to normal or low priority items in the simplest approach. Others might do a biased round robin H-H-N-H-H-N-H-H-L-H-H-N ..... kind of thing.

dave thieben wrote re: Real Life Single Responsibility Principle
on 01-07-2009 9:18 AM

Nice post.  However, I would remind people to also adhere to the DRY principle, in the chance that you have email-sending-related code that is the same in all three classes.

Tim Barcz wrote re: Real Life Single Responsibility Principle
on 01-07-2009 9:44 AM

@Scott

The strategies are rather simplistic at this point.  The Queued service uses a database table and there is a job running on an interval which looks at this table to see what needs to get send.

The real time email sends directly through SMTP.

We have other solutions using MSMQ that we'd like to go to but it's just not justifiable right now in terms of setup and cost when what we have works and works well.

Tim Barcz wrote re: Real Life Single Responsibility Principle
on 01-07-2009 9:45 AM

@Dave

Good point about DRY...you didn't get a chance to see the actual concrete implementations but they adhere to DRY.  See my comment reply above to "Scott" to understand.  Each piece of code that "sends" an email is unique for this application.

Tim Barcz wrote Real Life - Code Reuse
on 03-09-2009 2:37 PM

A few months ago I blogged about how we're using the single responsibility principle in our application

Community Blogs wrote Real Life - Code Reuse
on 03-09-2009 3:01 PM

A few months ago I blogged about how we're using the single responsibility principle in our application

Dale Smith wrote re: Real Life Single Responsibility Principle
on 03-09-2009 5:51 PM

Hi Tim,

I really dig Uncle Bob the SOLID principles, but many of my esteemed colleagues are still skeptical.  Which method do you find to be the most effective in convincing your team members to adhere to SRP when adding code or making changes?

a) Bribery (I myself am fond of fine chocolates)

b) Blackmail

c) Clockwork Orange-style ultra-violence

thanks.

meisinger wrote re: Real Life Single Responsibility Principle
on 03-10-2009 12:58 PM

i wonder if this wouldn't be a good place to implement a specification and strategy pattern?

if you simply created an abstract EmailService class with an abstract method of Send and an abstract method of Satisfies then you can simply have Queued and RealTime both inherit from the EmailService class

by doing this the RealmTime and Queued class "know" if the message is valid for their type of service (through the Satisfies specification method) rather than having the PriorityBased class "knowing" that information

not only does this give you SRP but this would also give you the open closed principle as well

and while i think that the you do have (or are implementing) DRY... there still seems to be something about the EmailService class that i feel is common across all of the services (e.g. the bounce email address, the smpt server name, validation etc...)

any ways... just my two cents

Chev wrote re: Real Life Single Responsibility Principle
on 03-24-2009 3:35 AM

meisinger

I like the idea of the strat pattern and I am busy learning the mechanics of it. Could you maybe post some sample code of how you would achieve this using strat pattern.

Cheers

Pharmb963 wrote re: Real Life Single Responsibility Principle
on 05-02-2012 1:23 PM

Hello! kkccdeg interesting kkccdeg site! I'm really like it! Very, very kkccdeg good!

buy generic viagra wrote re: Real Life Single Responsibility Principle
on 01-27-2013 7:08 AM

4vKT84 Great blog.Really thank you! Great.

buy stendra generic wrote re: Real Life Single Responsibility Principle
on 02-24-2013 3:43 PM

V621wM I really enjoy the blog post.Really thank you! Will read on...

buy clomid wrote re: Real Life Single Responsibility Principle
on 03-01-2013 3:06 AM

mY77ON Looking forward to reading more. Great blog article.Really looking forward to read more. Great.

buy discount viagra wrote re: Real Life Single Responsibility Principle
on 03-03-2013 3:31 PM

k1T15r I value the blog post.Thanks Again. Keep writing.

social bookmarks wrote re: Real Life Single Responsibility Principle
on 03-13-2013 12:00 PM

LqSjZN Very good article.Much thanks again. Fantastic.

bookmarks wrote re: Real Life Single Responsibility Principle
on 03-14-2013 11:03 PM

2h9J4F Very good article post.Really looking forward to read more. Keep writing.

buy social bookmarks wrote re: Real Life Single Responsibility Principle
on 03-25-2013 12:51 AM

GzzXGS A round of applause for your blog article.Much thanks again. Want more.

Social bookmarks wrote re: Real Life Single Responsibility Principle
on 04-04-2013 7:03 AM

UCPerD Say, you got a nice article post.Really looking forward to read more. Cool.

nonsense wrote re: Real Life Single Responsibility Principle
on 04-06-2013 5:27 AM

Fantastic blog post.Really looking forward to read more. Keep writing.

social bookmarking service wrote re: Real Life Single Responsibility Principle
on 04-13-2013 12:16 AM

aT9AbA Thanks again for the post. Great.

buy social bookmarks wrote re: Real Life Single Responsibility Principle
on 04-24-2013 8:03 AM

Xc1eKf I think this is a real great article post.Thanks Again. Keep writing.

digital camera guide wrote re: Real Life Single Responsibility Principle
on 05-14-2013 8:11 AM

flqHB5 I am so grateful for your blog post.Thanks Again. Really Great.

social bookmarking service wrote re: Real Life Single Responsibility Principle
on 06-06-2013 6:22 PM

3MYr8Y Great, thanks for sharing this article. Awesome.

cheap social bookmarks wrote re: Real Life Single Responsibility Principle
on 06-19-2013 11:23 AM

dUZTJQ Muchos Gracias for your post.Really looking forward to read more. Want more.

good social bookmarks wrote re: Real Life Single Responsibility Principle
on 06-22-2013 2:46 AM

7EEZsR Fantastic post.Thanks Again. Fantastic.

news and many more wrote re: Real Life Single Responsibility Principle
on 07-04-2013 8:48 AM

6rJ9mO Awesome blog article.Thanks Again. Fantastic.

cool news wrote re: Real Life Single Responsibility Principle
on 07-09-2013 4:48 PM

b9sSnr Appreciate you sharing, great post.Thanks Again. Will read on...

super news wrote re: Real Life Single Responsibility Principle
on 07-12-2013 1:01 AM

Ppom18 Appreciate you sharing, great blog.Really looking forward to read more. Really Great.

buy viagra online cheap wrote re: Real Life Single Responsibility Principle
on 07-24-2013 6:48 AM

Very informative blog.Much thanks again. Fantastic.

here wrote re: Real Life Single Responsibility Principle
on 07-25-2013 8:54 AM

Very good article.Really thank you! Awesome.

best news on earth wrote re: Real Life Single Responsibility Principle
on 07-26-2013 6:05 AM

3mha78 I really liked your blog post.Really looking forward to read more. Really Cool.

amazing news wrote re: Real Life Single Responsibility Principle
on 08-02-2013 10:26 AM

Wow, great blog article.Really thank you! Fantastic.

amazing news wrote re: Real Life Single Responsibility Principle
on 08-02-2013 2:57 PM

D4PmUa I loved your blog. Awesome.

greatest news wrote re: Real Life Single Responsibility Principle
on 08-03-2013 11:09 AM

55Olnw Say, you got a nice post.Really thank you! Keep writing.

great link buildng wrote re: Real Life Single Responsibility Principle
on 08-19-2013 10:54 PM

Llv3hE Great, thanks for sharing this blog.Really looking forward to read more. Awesome.

awesome links for you wrote re: Real Life Single Responsibility Principle
on 08-21-2013 6:32 AM

i9Ztwz Thanks again for the article post.Really thank you! Great.

great seo service wrote re: Real Life Single Responsibility Principle
on 09-03-2013 10:50 PM

SPYmFY Really appreciate you sharing this post.Much thanks again. Keep writing.

seo service wrote re: Real Life Single Responsibility Principle
on 09-07-2013 9:39 PM

LS1LKa This is one awesome article. Keep writing.

online business wrote re: Real Life Single Responsibility Principle
on 09-12-2013 4:00 PM

lueCg0 Very neat blog post. Keep writing.

pro link building wrote re: Real Life Single Responsibility Principle
on 09-24-2013 6:35 AM

aqmoLr I really like and appreciate your blog article. Want more.

great seo work wrote re: Real Life Single Responsibility Principle
on 09-29-2013 7:13 AM

SYhrFA I cannot thank you enough for the article. Really Cool.

awesome linkbuilding site wrote re: Real Life Single Responsibility Principle
on 10-01-2013 12:12 AM

4nuUPp I cannot thank you enough for the blog post.Really looking forward to read more. Really Cool.

link building team wrote re: Real Life Single Responsibility Principle
on 10-15-2013 12:49 PM

e7Irlm Fantastic article.Thanks Again. Really Cool.

top seo guys wrote re: Real Life Single Responsibility Principle
on 10-24-2013 9:06 AM

X0c8A4 I think this is a real great post.Thanks Again. Will read on...

take a look at it! wrote re: Real Life Single Responsibility Principle
on 10-31-2013 1:42 AM

4g6rNg Thanks so much for the blog article.Thanks Again.

great link building wrote re: Real Life Single Responsibility Principle
on 11-20-2013 9:19 PM

aKKo1B Hey, thanks for the article.Really thank you!

awesome seo thing wrote re: Real Life Single Responsibility Principle
on 12-15-2013 11:21 AM

5hzBJ1 Wow, great blog post.Much thanks again. Really Cool.

stunning seo guys wrote re: Real Life Single Responsibility Principle
on 01-10-2014 9:36 AM

wIbiSW I truly appreciate this article post.Thanks Again. Much obliged.

stunning seo guys wrote re: Real Life Single Responsibility Principle
on 02-28-2014 5:53 AM

LXPOHr Awesome blog article. Much obliged.

good seo guys wrote re: Real Life Single Responsibility Principle
on 03-12-2014 6:28 AM

kWArZj Muchos Gracias for your post.Really thank you! Really Cool.

nice seo guys wrote re: Real Life Single Responsibility Principle
on 03-22-2014 1:24 PM

cR2HtI Great, thanks for sharing this article.Much thanks again. Really Cool.

check it out wrote re: Real Life Single Responsibility Principle
on 04-01-2014 5:58 AM

8wi35U Thanks again for the article post.Really thank you! Cool.

check it out wrote re: Real Life Single Responsibility Principle
on 04-01-2014 9:58 AM

JNInow Really appreciate you sharing this post. Much obliged.

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)