KakimotOnline

July 22, 2009

Singleton (Anti-) Pattern

Filed under: programming, refactoring, software design, testing — Tags: , , — nandokakimoto @ 3:51 am

I’ve implemented my first design patterns at college, while creating a web system during the software engineer course. My classmates and I needed a facade class with a single instance of it throughout the system. So, because we’re really smart, we’ve applied the Facade and Singleton pattern. Actually, we’ve implemented the patterns without knowledge of the design patterns catalog. For us, it was just a way to get what we need.

This week, while doing my daily work, I realized how dangerous the Singleton pattern is. Well, I would have noticed it before, if I have used Test-First Programming. Even knowing the benefits of TDD, I decided to write some code in advance, since I don’t have much experience on the platform used and on its supported tests framework.

My task was to create a GPS abstraction and use it in a mobile Navigator module. My first thought was making my GPS abstraction a Singleton class. It looked very obvious for me: a mobile device has only one GPS and different GPS intances will provide the same data set. So, what I need is just a single GPS instance troughout the system.

After some minutes writing code, I’ve created abstractions similar to the Java sample below.

GPSProvider.java

import java.util.List;

public class GPSProvider implements LBSPositionObserver {

 private static GPSProvider INSTANCE = new GPSProvider();
 private Position lastCoordinate;
 private List<GPSListener> listeners;

 private GPSProvider() {
 this.listeners = new ArrayList<GPSListener>();
 }

 //retrive the class instance
 public static GPSProvider GetInstance() {
 return INSTANCE;
 }

 // perform GPS initialization
 public void initGPSService() {
 (...)
 }

 // add a new listener to the gps class
 public void attach(GPSListener listener) {
 this.listeners.add(listener);
 }

 // remove a listener from the class list
 public void dettach(GPSListener listener) {
 this.listeners.remove(listener);
 }

 @Override
 // set lastCoordinate and notify all listeners about the update
 public void positionUpdated(Position position) {
 this.lastCoordinate = position;
 for ( GPSListener listener : this.listeners ) {
 listener.positionUpdated(position);
 }
 }

 @Override
 // notify all listener about the update
 public void setStatus(int status) {
 for ( GPSListener listener : this.listeners ) {
 listener.statusUpdated(status);
 }
 }

 // return the last known coordinate
 public Position getLastCoordinate() {
 return this.lastCoordinate;
 }

}

GPSListener.java

public interface GPSListener {

 void positionUpdated(Position position);

 void statusUpdated(int status);

}

LBSPositionObserver.java – native GPS interface

public interface LBSPositionObserver {

 void positionUpdated(Position position);

 void setStatus(int status);

}

Navigator.java

public class Navigator implements GPSListener {

 private NavigatorObserver observer;

 public Navigator(NavigatorObserver observer) {
 this.observer = observer;
 }

 // start navigation by listening to gps updates
 public void navigate(Route route) {
 GPSProvider gps = GPSProvider.GetInstance();
 gps.attach(this);
 }

 // pause navigation by not receiving gps updates
 public void pause() {
 GPSProvider gps = GPSProvider.GetInstance();
 gps.dettach(this);
 }

 @Override
 // everytime the position is updated, the navigator gives directions if needed
 public void positionUpdated(Position position) {
 // navigate user through route.
 int step = this.verifyStepUpdated();
 if ( step != -1 ) {
 this.observer.StepUpdated(step);
 }

 if ( this.achievedDestination() ) {
 this.observer.DestinationAchived(position);
 }
 }

 // calculate if achieved destination
 private boolean achievedDestination() {
 (...)
 }

 // verify is have to change direction
 private int verifyStepUpdated() {
 (...)
 }

 @Override
 public void statusUpdated(int status) {
 // send status to end user.
 }
}

Now, since I’ve finished my Navigator module, I want to test it to make sure it’s working correctly. In order to test the Navigator module, I need a GPS data log and a route to walk through it, simulating a person walking and being navigated by the system. The route is not a problem because I pass it as a parameter of “navigate” method. However, there is no way to simulate a GPS log with the code above, unless I use some Dependency Injection Framework, which is not the case.

That’s the Singleton disadvantage. I can’t inject a GPS mock in my Navigator module because I always use the native gps implementation represented in my Singleton GPSProvider class. Everytime I need some GPS information, I use the GPSProvider.GetInstance() static method to retrieve the only GPS instance I have access to.

To solve this problem, I found a simple solution: not using Singleton. I removed  the Singleton pattern from GPSProvider and change every class that uses GPSProvider.GetInstance() to receive the current GPS intance. In the Navigator module, I passed the GPS instance through its class’ constructor.

GPSAbstractProvider.java

import java.util.ArrayList;
import java.util.List;

public abstract class GPSAbstractProvider {

 private List<GPSListener> listeners;

 public GPSAbstractProvider() {
 this.listeners = new ArrayList<GPSListener>();
 }

 public abstract void initGPSService();

 public void attach(GPSListener listener) {
 this.listeners.add(listener);
 }

 public void dettach(GPSListener listener) {
 this.listeners.remove(listener);
 }

 public void notifyPositionUpdated(Position position) {
 for ( GPSListener listener : this.listeners ) {
 listener.positionUpdated(position);
 }
 }

 public void notifyStatusUpdated(int status) {
 for ( GPSListener listener : this.listeners ) {
 listener.statusUpdated(status);
 }
 }

}

GPSProvider.java

public class GPSProvider extends GPSAbstractProvider implements LBSPositionObserver {
 private Position lastCoordinate;

 private GPSProvider() {
 super();
 }

 @Override
 // perform GPS initialization
 public void initGPSService() {
 (...)
 }

 @Override
 public void positionUpdated(Position position) {
 this.lastCoordinate = position;
 this.notifyPositionUpdated(position);
 }

 @Override
 public void setStatus(int status) {
 this.notifyStatusUpdated(status);
 }

 public Position getLastCoordinate() {
 return this.lastCoordinate;
 }

}

Navigator.java

public class Navigator implements GPSListener {

 private NavigatorObserver observer;
 private GPSAbstractProvider gps;

 public Navigator(NavigatorObserver observer, GPSAbstractProvider gps) {
 this.observer = observer;
 this.gps = gps;
 }

 public void navigate(Route route) {
 this.gps.attach(this);
 }

 public void pause() {
 this.gps.dettach(this);
 }

 @Override
 public void positionUpdated(Position position) {
 // navigate user through route.
 int step = this.verifyStepUpdated();
 if ( step != -1 ) {
 this.observer.StepUpdated(step);
 }

 if ( this.achievedDestination() ) {
 this.observer.DestinationAchived(position);
 }
 }

 private boolean achievedDestination() {
 (...)
 }

 private int verifyStepUpdated() {
 (...)
 }

 @Override
 public void statusUpdated(int status) {
 // send status to end user.
 }
}

Much better! Notice that I still have just one single instance of my GPS class. All I have to do is creating my GPS at the beginning of the program and pass it through classes that use it.
Doing this, testing my code became very simple. I inject my GPS mock to simulate GPS data in my tests,  just as below.

NavigatorTest.java

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;

public class NavigatorTest extends TestCase implements NavigatorObserver {

 private Navigator navigator;
 private GPSAbstractProvider gps;

 public void testNavigate() throws Exception {
 List<Position> gpsPositions = new ArrayList<Position>();
 this.addPositions(gpsPositions);
 this.gps = new GPSTestProvider(gpsPositions);

 this.navigator = new Navigator(this, this.gps);
 this.navigator.navigate(this.createSimpleRoute());

 gps.initGPSService();

 assert(...);
 assert(...);
 }

 private Route createSimpleRoute() {
 (...)
 }

 private void addPositions(List<Position> gpsPositions) {
 (...)
 }

 @Override
 public void DestinationAchived(Position destination) {
 (...)
 }

 @Override
 public void StepUpdated(int step) {
 (...)
 }

}

As you can see, I can use any GPS provider in my tests, making them much more easy and flexible.
In addition to the disavantage presented, Alex Miller discuss some points why he hates Singleton pattern.
From here, trying avoiding this pattern in situations like that. Think twice before applying Singleton in your project.

See you


Fernando

February 21, 2009

Refactoring to Command Pattern

Filed under: programming, refactoring, software design — Tags: , , — nandokakimoto @ 1:29 am

I’ve spent the last two weeks reading another refactoring famous reference. After Refactoring, I decided to read Refactoring to Patterns, which is also very good, and today I’ll share one sample of book’s refactoring catalog: Replace Conditional Dispatcher with Command. In this example, you will be able to see some of book’s approach and how this practice improves code quality.

“Conditional logic is used to dispatch requests and execute actions. Create a Command for each action. Store the Commands in a collection and replace the conditional logic with code to fetch and execute Commands.”

A lot of systems receive and manipulate requests, which in some cases are processed by conditional statements. There is no problem if your conditional mecanisn is small and treats just a few number of requests. However, if your if-else’s start growing, it’s time to search for betters solutions. A good option is change from conditional statements to the Command pattern, providing runtime flexibility and avoiding inflated code.

To implement the pattern, you just separate each block of the conditional dispatcher in a separated command class with a common execute method responsable for executing a specific encapsulated logic. So, besides of calling different routines depending on the received request, you will now just call the excute method for all of them.

Benefits

  • provide a simple mecanism to execute different behaviors in a common way.
  • allow runtime changes in which requests are manipulated and how they are manipulated.
  • easy implementation with trivial code.

Disavantage

  • complicates a project when a conditional statement it’s enough.

Now, let’s examine a real-life example. Imagine you have the code below:

image12

In this example, the RequestHandler class is responsable for manipulating requests depending on its actionName parameter in a big conditional statement. It isn’t a good approach at all,  so let’s start refactoring it. The first step is apply extract method on each conditional body. This step will result in the following code.

image21

I compile and test to make sure that I didn’t break anything.

The next step creates concrete commands for each existing if-else block. So, we will add two new classes to the project: ErrorHandler and SuccessHandler, and later apply move method to the existing methods in the RequestHandler class. That’s is the result.

image31

image4

image5

Again I compile and test.

With the concrete commands created, it’s time to create the command interface. Note that both commands have different methods name and we still use the conditional statement to instantiate the correct concrete command.  Let’s use a Handler interface with an execute method to manipulate the requests. In addition I used move method in getMessage and preparedEmail because, at this moment, they are specific to its respectively concrete handler. Here is how the code looks like after this changes.

image6

image7

image8

image9

Compile and test one more time.

To complete this refactor we must call Handler.execute() for all requests, independently of its type. This is possible by creating a factory method, which returns the correct handler depending on the request’s actionName. However, the conditional statement will continue making part of the code. So, I’ll use a different solution. To define which concrete handler instatiate, I will make use of a Map of actionName, mapping the name of the request to the correct handler. The final result is shown below.

image10

Now, the code is much more clean, extensible and readable.

This is just a little of what Refactoring to Patterns addresses. There is a lot more funny things there.
If you got interedted, you can find the whole refactorings catalog here. Enjoy it.

See you,


Fernando

February 1, 2009

Refactoring: write code that humans can understand

Filed under: programming, refactoring — Tags: , — nandokakimoto @ 6:04 pm

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

This is a famous phrase from Martin Fowler and one of the most relevant motivations for refactoring. Martin defines refactoring as “a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior”. However, why should I change my piece of code if it’s perfectly running?

Well, refactoring has four main motivations:

  1. Refactoring improve software project: Without refactoring, your software’s project start deteriorating. As more as people change it, more damaged and more difficult to understand it is. Refactoring is like putting things in their right place and helps to keep code’s quality.
  2. Refactoring makes software easier to understand: programming is like talking with computers. When you are programming you’re telling computers what to do. However, if you talk in a difficult language, which just computers understand, the future programmer will lost a precious time trying to decode what you are telling before start creating code. Refactoring helps keeping your code more readable.
  3. Refactoring helps finding bugs: while refactoring you’re working on code comprehension and structure. With a better code comprehension, it’s easier to look at assumptions you’ve made before and find that they were wrong.  
  4. Refactoring helps programming faster: the other three motivations result in this last one: refactoring makes you create code faster. Refactoring your code frequently makes your code ease to understand and change. So, if you have to add new functionalities, you will not need to lose time trying to figure out what that piece of code means. You go straightforward and make what have to be done quickly.

As I’ve said on the motivations, refactoring must be a programming habit. Every time you change your code, you have the responsibility to deliver it better than when you got it. So do refactoring every time you add new functions, fix a bug or review the code.

Now that you know why refactoring, you need to know how to do it. The essential thing is: have solid tests. Remember that refactoring alters program internal structure without changing its external behavior, which means you must refactor without adding new bugs. One way to guarantee that you’re not adding bugs to your project is running your tests every time you do a refactoring in your code. So, change, compile and test. Tests give you the confident to refactoring and, most of times, give you the agility to write code right and simple.

To know more about refactoring, I recommend reading Martin Fowler’s book Refactoring: Improving the Design of Existing Code. The book comes with a refactoring catalog which shows you a lot of refactoring techniques and samples; it’s really a very good reading. Now, it’s up to you.

See you,


Fernando

Blog at WordPress.com.