Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a blog where users can post comments.

When creating a comment, various things happen:

  • creating the comment object, associations, persisting
  • sending notification emails to post's author given his preferences
  • sending notification to moderators given their preferences
  • updating a fulltext database for search
  • ...

I could put all this in the controller, but what if I want to reuse this code ? e.g. I would like to provide an API for posting comments.

I could also put this in the model, but I wonder if I won't lose flexibility by doing so. And would it be acceptable to do all of this from the model layer ?

What would you do ?

share|improve this question

4 Answers 4

You can use the Event-Observer pattern for this: Dispatch an event that a post message was saved and let the observers of that event to do the required actions (eg: send notifications, update full text search): http://en.wikipedia.org/wiki/Observer_pattern

share|improve this answer

I'm thinking of doing it this way:

[ControllerMethod]
PostComment (CommentModel comment)
{
    CommentsRepository.SaveComment (comment);

    NotificationBusinessLogic.SendPostAuthorNotification (comment);
    NotificationBusinessLogic.SendAdministratorNotification (comment);

    OperationBusinessLogic.UpdateFullTextSearch ();
}

You can then expose any BL methods you seem appropriate to external users and through this achieve reuse.

share|improve this answer

Your controller should call one method in your Business Layer passing it the parameters needed to effect a comment save.

The business layer method is the "orchestration" method. It knows what to do and it know what all needs to be done. This method in turn may call other private/public methods or specialized object's method to get the job done.

The key point is that the business rules of what needs to happen when a comment is saved is encapsulated in one method of the business layer. Other controllers can call this method without needing to know everything that needs to be done. Similarly, if you need to add additional steps in the process, you need only change the implementation in the business layer.

public class BusinessLayer
{
  public int SaveComment(Comment comment)
  {
    DataLayer.SaveComment(comment);
    NotificationsManager.SendPostAuthorCommentNotification(comment.PostId);
    NotificationsManager.SendModeratorNotification(comment.PosId)
    SearchManager.InsertIntoFullTextIndex(comment.Id, comment.Description);
  }
}

By the way, these notifications and full text indexing etc. should be done "out of band". Meaning you should an external process to actually do all the work. For example, you could post a "message" in an MSMQ message queue. It takes an instant to post a message and the user who posted the comment is not waiting for all of the processing to be completed.

You can then have another process (or processes) that process the messages in MSMQ. These processes can take their own sweet time to get the job done and these processes can use the same Business Layer (if needed - or the "managers") to get the work done.

The design will allow your application to scale and those posting comments will see minimal response times.

share|improve this answer

If you have this code in the Controllers then you would have an aenemic domain and wouldn't have proper Separation of Concerns.

The Controllers are in Presentation Tier of your application and should deal with input/output. The Models are in Domain Tier and are a more appropriate candidate to contain business logic.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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