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:
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);
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!
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.
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
When would you use the Builder Pattern?
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.
Related
Chapter 3 of "Clean Code" makes it pretty clear that keeping the number of function arguments small is good practice. I'm now trying to avoid anything beyond dyads. It's been working out ok so far but I keep running into situations where I need three arguments to construct an object. Of course I could create an argument object to solve this but then I'd have to choose two of the three arguments to group together and that does not always make sense. So my question is if this guideline applies to constructors as well or if I shouldn't worry about triad constructors.
These "rules" are guidelines and it depends on the use case. In general, it's a good idea to keep the number of arguments low. Besides using composite types as arguments, there are some common patterns for this:
The classic builder pattern, or what I prefer, the modern variation fluent builder pattern
E.g.:
Email email = Email.EmailBuilder()
.setFrom("Test#gmail.com")
.setTo("mail#gmail.com")
.setSubject("Test with only required Fields")
.setContent(" Required Field Test")
.build();
I have a simple design problem - I am looking for the best pattern to implement a simple functionality. Let's say, I am going to create an xml message in java. This message consists of many fields in different logic groups.
So, the first idea - create a class to set all fields. I can do it one method (which will be really long...) or split the method into multiple smaller (for each of the logical groups). However, I don't think it is a good approach, because the class will be really long and difficult to mantain.
The second idea is to create a functional interface and some implementations for different groups, for instance GroupXxxSetter, GroupYyySetter, etc. I can create and keep all instances in a list or a set and call the method defined inside the interface for each object stored inside the collection. It seems to be very similar to the 'Chain of responsibility' pattern. However, the idea of this pattern is different, so I am not sure if it is a good idea to use this pattern in my case.
Should I use the 'chain of responsibility' pattern here? Or, maybe there is something better?
Thanks in advance.
Should I use the 'chain of responsibility' pattern here?
Clearly, no. You don't have the notion of candidate responsible to respond to a request. All elements will do a processing.
Or, maybe there is something better?
You have multiple possibilities.
Your context is not totally set. So it is hard to propose one rather than another.
I may propose you a implementation with the Builder pattern (Java Effective reference and not GOF).
For each logic group, you could have a specific class.
You would also have a composite class that is composed of logic group instances.
Instead of providing a public constructor or setters that prevent immutability and that can make rules validation cumbersome, you could use the Builder pattern for each one logic group class and in the composite class, you could use the same kind of Builder pattern where you will build the final message from the previously created logic group instances.
You could so create the instances in this way :
OneLogicGroup oneLogicGroup = OneLogicGroup.builder().fieldXXX(...).fieldYYY(...).build();
AnotherLogicGroup anotherLogicGroup = AnotherLogicGroup .builder().fieldXXX(...).fieldYYY(...).build();
MyMessage myMessage = MyMessage.builder().oneLogicGroup(oneLogicGroup).anotherLogicGroup(anotherLogicGroup).build().
I can create and keep all instances in a list or a set and call the
method defined inside the interface for each object stored inside the
collection.
It seems referring to a structural concern.
It is not directly related to the creation of the object. It is much related to how to share the created objects.
The flyweight pattern addresses this need and may be used conjointly with the presented builder Pattern.
If I have a constructor for an immutable object that requires several (4+ parameters), is having a single constructor with all the required parameters the correct approach?
I feel this becomes a candidate for the Builder pattern, but I also feel like shying away from it since the parameters are required, and a Builder seems more appropriate when you get to pick and choose.
The example in my mind is a model object that does not change once created.
If you want to create an immutable object, you have to provide a constructor with all necessary fields.
You cannot set the state partially as later you would have to add some notion of "setters" which would by definition add mutability.
Builder pattern is really about partial object building.
Both options have their drawbacks, as you suggest. A four argument constructor is hard to use correctly and makes the code hard to read. However, it communicates the intent that all parameters are mandatory.
A builder would be easier to use and make the code easier to read, but communicate the intent that the arguments are optional.
Since code is more often read than written, I recommend to use the option that promotes readability in this case. Go for a builder and make sure that all paramters are validated when the build() method is called to fail as fast as possible when using the builder incorrectly. Use javadoc to assist with communicating that all parameters are mandatory.
After comming from Ruby world, I'm having little problems doing TDD in Java. The biggest issue is when I have application that is just communicating with external API.
Say I want to just fetch some data from Google Calendar, or 5 tweets from some Twitter user and display it.
In Ruby, I don't have any problems, because I can monkey-patch the API library in tests directly, but I have no such option in Java.
If I think about this in terms of MVC, my model objects are directly accessing the API through some library. The question is, is this bad design? Should I always wrap any API library in some interface, so I can mock/stub it in Java?
Because when I think about this, the only purpose of that interface would be to simulate (please don't kill me for saying this) the monkey-patch. Meaning that any time I use any external resource, I have to wrap each layer in interface that can be stubbed out.
# do I have to abstract everything just to do this in Java?
Twitter.stub!(:search)
Now you might say that I should always abstract away the interface, so I can change the underlying layer to anything else. But if I'm writing twitter app, I'm not going to change it to RSS reader.
Yes, I can add for example Facebook and then it would make sense to have interface. But when there is no other resource that can be substituted for the one I'm using, than I still have to wrap everything in interfaces to make it testable.
Am I missing something, or is this just a way to test in the Java world?
Using interfaces is just generally good practice in Java. Some languages have multiple inheritance, others have duck typing, Java has interfaces. It's a key feature of the language, it lets me use
different aspects of a class in different contexts and
different implementations of the same contract without changing client code.
So interfaces are a concept you should embrace in general, and then you would reap the benefits in situations like this where you could substitute your services by mock objects.
One of the most important books about Java best practices is Effective Java by Joshua Bloch. I would highly suggest you to read it. In this context the most important part is Item 52: Refer to objects by their interfaces. Quote:
More generally, you should favor the use of interfaces rather than
classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface
types. The only time you really need to refer to an object’s class is when you’re
creating it with a constructor.
And if you take things even further (e.g. when using dependency injection), you aren't even calling the constructor.
One of the key problems of switching languages is that you have to switch the way of thinking too. You can't program language x effectively while thinking in language y. You can't program C effectively without using pointers, Ruby not without duck typing and Java not without Interfaces.
Wrapping the external API is the way I would do this.
So, as you already said, you would have an interface and two classes: the real one and the dummy implementation.
Yes, it may seem unreasonable from the perspective of some services indeed being specific, like Twitter. But, this way your build process doesn't depend on external resources. Depending on external libraries isn't all that bad, but having your tests depend on actual data present or not present out there on the web can mess up the build process.
The easiest way is to wrap the API service with your interface/class pair and use that throughout your code.
I understand that what you want are Mock objects.
As you described it, one of the ways one can generate "test versions" of objects is by implementing a common interface and using it.
However, what you are missing is to simply extend the class (provided that it is not declared final) and override the methods that you want to mock. (NB: the possibility of doing that is the reason why it is considered bad form for a library to declare its classes final - it can make testing considerably harder.)
There is a number of Java libraries that aim in facilitating the use of Mock objects - you can look at Mockito or EasyMock.
Mockito is more handy and like your ruby mocks.
You can "monkey-patch" an API in Java. The Java language itself does not provide specific means to do it, but the JVM and the standard libraries do. In Ruby, developers can use the Mocha library for that. In Java, you can use the JMockit library (which I created because of limitations in older mocking tools).
Here is an example JMockit test, equivalent to the test_should_calculate_value_of_unshipped_orders test available in Mocha documentation:
#Test
public void shouldCalculateValueOfUnshippedOrders()
{
final Order anOrder = new Order();
final List<Order> orders = asList(anOrder, new Order(), new Order());
new NonStrictExpectations(Order.class)
{{
Order.findAll(); result = orders;
anOrder.getTotalCost(); result = 10;
}};
assertEquals(30, Order.unshippedValue());
}
I just found myself creating a class called "InstructionBuilderFactoryMapFactory". That's 4 "pattern suffixes" on one class. It immediately reminded me of this:
http://www.jroller.com/landers/entry/the_design_pattern_facade_pattern
Is this a design smell? Should I impose a limit on this number?
I know some programmers have similar rules for other things (e.g. no more than N levels of pointer indirection in C.)
All the classes seem necessary to me. I have a (fixed) map from strings to factories - something I do all the time. The list is getting long and I want to move it out of the constructor of the class that uses the builders (that are created by the factories that are obtained from the map...) And as usual I'm avoiding Singletons.
A good tip is: Your class public API (and that includes it's name) should reveal intention, not implementation. I (as a client) don't care whether you implemented the builder pattern or the factory pattern.
Not only the class name looks bad, it also tells nothing about what it does. It's name is based on its implementation and internal structure.
I rarely use a pattern name in a class, with the exception of (sometimes) Factories.
Edit:
Found an interesting article about naming on Coding Horror, please check it out!
I see it as a design smell - it will make me think if all those levels of abstraction are pulling enough weight.
I can't see why you wanted to name a class 'InstructionBuilderFactoryMapFactory'? Are there other kinds of factories - something that doesn't create an InstructionBuilderFactoryMap? Or are there any other kinds of InstructionBuildersFactories that it needs to be mapped?
These are the questions that you should be thinking about when you start creating classes like these. It is possible to just aggregate all those different factory factories to just a single one and then provide separate methods for creating factories. It is also possible to just put those factory-factory in a different package and give them a more succinct name. Think of alternative ways of doing this.
Lots of patterns in a class name is most definitely a smell, but a smell isn't a definite indicator. It's a signal to "stop for a minute and rethink the design". A lot of times when you sit back and think a clearer solution becomes apparent. Sometimes due to the constraints at hand (technical/time/man power/etc) means that the smell should be ignored for now.
As for the specific example, I don't think suggestions from the peanut gallery are a good idea without more context.
I've been thinking the same thing. In my case, the abundance of factories is caused by "build for testability". For example, I have a constructor like this:
ParserBuilderFactoryImpl(ParserFactory psF) {
...
}
Here I have a parser - the ultimate class that I need.
The parser is built by calling methods on a builder.
The builders (new one for each parser that needs to be built) are obtained from builder factory.
Now, what the h..l is ParserFactory? Ah, I am glad you asked! In order to test the parser builder implementation, I need to call its method and then see what sort of parser got created. The only way to do it w/o breaking the incapsulation of the particular parser class that the builder is creating is to put an interception point right before the parser is created, to see what goes into its constructor. Hence ParserFactory. It's just a way for me to observe in a unit test what gets passed to the constructor of a parser.
I am not quite sure how to solve this, but I have a feeling that we'd be better off passing around classes rather than factories, and Java would do better if it could have proper class methods rather than static members.