views:

55

answers:

3

I need to create an email-notification service (as a part of a bigger project).

It will be used to send several types of notification messages which are based on html-templates.

I can design it in two ways:

  1. The first way is based on the builder pattern. It's universal (as I think) and can handle all necessary cases. But it's not very convenient for those who will use it. The typical usage would look like this:

    messageBuilder
       .put("name", "John Doe")
       .put("company", companyObj)
       .processPattern(pattern)
       .send(addresses, subject);
    
  2. The second way is to implement all cases explicitly. It means that usage code (shown below) will be as simple as possible but we'll have to modify API (add new methods) every time when we need to handle any new case.

    messageSender.sendPersonExpenceNotification(addresses, "John Doe", company); 
    

Which one is better? Why? (the language is Java if it matters)

Thanks!

A: 

Effective Java 2nd Edition, Item 2: Consider a builder when faced with many constructor parameters.

The builder pattern is more readable, especially as you have potentially many more parameters. That said, it's usually more common to have specific setName, setCompany, etc methods for a builder. That way you can also enforce type-safety, e.g. setSomeBoolean(boolean), setSomeInt(int), etc.

A builder pattern also allows you to set default values to some parameters, and user can conveniently override the default on some parameters. Providing methods to simulate this involves writing many overloads, which exacerbate the problem further.

Related questions

polygenelubricants
A: 

Nowadays, the most favored design pattern relies upon "fluent" builder. This way, you gain the genericity of the builder, with an understandable interface.

Implementing it is rather mundane, considering it's only a matter of well choosing your method names.

Good real world examples are all the FEST* libraries.

Riduidel
+2  A: 

I think the answer is to use both. I would suggest using the more generic approach (the message builder) in the API and then providing client-side convenience functions/classes that are simple to use for specific tasks. This way the API doesn't have to update when you add new cases but the client can still use the most direct call for what they're trying to do.

bshields
Really. I've just thought about the same. +1.
Roman