Design patterns in the real world: Strategy

Quite some software engineers think that design patterns are some overly complicated, mythical, abstract things that bring no practical value to software development. This is unfortunate. In order to prove they are indeed something real, in this (and some upcoming) post(s) we are going to take a look on a few examples on how real software products implement some of the GoF design patterns. Today, we are going to visit Strategy, from HotSpot’s point of view. (See the previous post about Flyweight here).

Continue reading “Design patterns in the real world: Strategy”

Design patterns in the real world: Flyweight

Quite some software engineers think that design patterns are some overly complicated, mythical, abstract things that bring no practical value to software development. This is unfortunate. In order to prove they are indeed something real, in this (and some upcoming) post(s) we are going to take a look on a few examples on how real software products implement some of the GoF design patterns. The first one to be examined is Flyweight.

Continue reading “Design patterns in the real world: Flyweight”

Composite Design Pattern Kata

Today’s post is nothing elevated, just two examples from which one can understand this powerful design pattern.

First, let’s do a quick recap, how the pattern actually looks like: 

(if you’re new to design patterns, please find a detailed description here)

The exercises are the following (note that the second one usually looks easier, because it’s easier to imagine. However, you are gonna have a harder time if you want to do that properly using TDD. Mocking recursive structures is not the easiest thing to do):

  1. Implement an application that can draw(no, you don’t really have to draw, just implement the data structures) pictures using rectangles and circles. A picture can be made from primitives (rectangles and circles), primitives combined with other pictures (one or more primitives and at least one other picture – which is composed of primitives), and several pictures combined. (Spoiler: circles and rectangles are leaves, pictures are composite objects)
  2. Implement an application that can compute (yes, you really have to compute) the size of a directory. The size of a directory is equal to the sum of all the files it contains plus the size of its subdirectories. (Hint: you might want to wrap java.io.File objects inside your Leaf and Composite classes. Spoiler: in this case plain files are leaves, directories are composites).

You can find a solution to the second problem here (implementation in Java, unit tested with JUnit and Mockito).

Builder vs. Large arg-list constructor

Today I was browsing one of our module’s code. I wasn’t looking for anything in particular, I just wanted to familiarize myself with that part of the system. However, I found something strange; the code was full of object constructions like:

private MyObject myObject = new MyObject(null, null, "", "", importantData, importantData2);

You might say, yes, this class does way too many things if it takes this many arguments. Believe it or not, it actually made sense to keep those data together. The real problem was passing around null and dummy values across the system. And the situation was even worse in case of unit tests.

Let’s see a toy example – a.k.a. code that’s not confidential. We consider the class:

import java.util.Date;

public class User {

	private String userName;
	private String password;
	private String nickName;
	private Date lastOnline;
	private Address address;
	private Balance balance;

	public User(String userName, String password, String nickName,
			Date lastOnline, Address address, Balance balance) {
		this.userName = userName;
		this.password = password;
		this.nickName = nickName;
		this.lastOnline = lastOnline;
		this.address = address;
		this.balance = balance;
	}
}

For the sake of the example, let’s suppose we have object constructions like:

User user = new User("tamasgyorfi", "lotsOfAsterisks", "", null, null, null);

User anotherUser = new User("", "", "chaster", new Date(), null, null);

Well, this is 100% functional, but not that clean. Null values and empty strings make these lines sort of “noisy”. How do we make this cleaner? I think in such situations it is worth to give Builder Design Pattern a try, as it makes object construction more straightforward.

This is how I usually do it, in six easy steps: I

  1. create a new class and name it UserBuilder (I like to add the word Builder so others know what they’re facing)
  2. copy all the fields of the object under construction into the builder
  3. (as far as I know) Eclipse is not able to generate the methods I need, so I have it generate all the setters for the fields
  4. with find/replace I replace all the words “set” with “with”. Also replace the return types from void to UserBuilder
  5. have all the methods return this
  6. create a method named “build”. It does the actual construction and returns the object constructed.

After step 6, we have something like this:

import java.util.Date;

public class UserBuilder {

	private String userName;
	private String password;
	private String nickName;
	private Date lastOnline;
	private Address address;
	private Balance balance;

	public UserBuilder withUserName(String userName) {
		this.userName = userName;
		return this;
	}

	public UserBuilder withPassword(String password) {
		this.password = password;
		return this;
	}

	public UserBuilder withNickName(String nickName) {
		this.nickName = nickName;
		return this;
	}

	public UserBuilder withLastOnline(Date lastOnline) {
		this.lastOnline = lastOnline;
		return this;
	}

	public UserBuilder withAddress(Address address) {
		this.address = address;
		return this;
	}

	public UserBuilder withBalance(Balance balance) {
		this.balance = balance;
		return this;
	}

	public User build() {
		return new User(userName, password, nickName, lastOnline, address,
				balance);
	}

}

So we can replace the object constructions mentioned above with these calls:

UserBuilder builder = new UserBuilder();
User user = builder.withUserName("tamasgyorfi")
				.withPassword("lotsOfSterisks")
				.build();

and similarly:

UserBuilder builder = new UserBuilder();
User anotherUser = builder.withLastOnline(new Date())
				.withNickName("chaster")
				.build();

Cleaner, more straightforward, don’t care things are left out and only relevant arguments are mentioned. And last but not least object construction is moved to one place and it’s not spread across multiple classes.

Note: the ideas above are only valid when your objects are not required to be immutable.

Rediscovering Strategy pattern

A few weeks  ago, I had this idea of organizing an in-house self development group. Since then, we have already had three weekly meetings, with a kind of tricky exercise to solve. Continue reading “Rediscovering Strategy pattern”