Singleton: A Design Pattern Past Its Time?

I recently had a conversation with someone and in passing I said something along the lines of singleton being a pointless design pattern and something that I’d try my best to not use. They said there were lots of reasons for a singleton, then we moved onto a different topic.  However, it’s gotten me thinking, is there really a reason for the use of a singleton?  I did some digging through StackOverflow and found a few reasons as to why to use one — but even then, it wasn’t a glowing endorsement.  Nothing I’ve seen has really made me change my mind from the fact that the singleton pattern is something with very limited usability and most people seem to view the singleton pattern as a pox on the programming world.

Personally, I’d stay as far as way as possible from them unless absolutely necessary.

What do y’all think?  Is it now an anti-pattern or is it something that is still useful?

Testing in Java: Part II – Writing a Fake

In the first part we talked about the domain objects and how to test a domain object.  Now it’s time to look at how to persist them to an in-memory data store for testing purposes.  We’ll be writing this in such a way that at a later date you can replace the in-memory representation with a strategy that persists the data to disk.  So, let’s jump right into the code starting with the data access object interface.

package com.laneholloway.unittestingexample.database.dao;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.UUID;

/**
 * A simple Data Access Object
 */
public interface MyDao {
    public boolean exists(UUID guid);
    public MyItem get(UUID guid);
    public boolean save(MyItem item);
    public void delete(UUID guid);
}

Looking at the code you can easily tell that there are some simple CRUD operations and an exists command. Any datasource that we want to write the data to must implement these commands and inside the program, we should only use these commands to interact with the object. In order to facilitate the testing of the framework, I’ve created a simple in memory dao and placed it into the test directory that maven creates.

package com.laneholloway.unittestingexample.database.dao;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * An in-memory representation of a datastore using MyDao
 */
public class MyInMemoryDao implements MyDao {
    private Map<UUID, MyItem> storedItems;

    public MyInMemoryDao() {
        this.storedItems = new HashMap<UUID, MyItem>();
    }

    @Override
    public boolean exists(UUID guid) {
        return this.storedItems.containsKey(guid);
    }

    @Override
    public MyItem get(UUID guid) {
        return this.storedItems.get(guid);
    }

    @Override
    public boolean save(MyItem item) {
        this.storedItems.put(item.getGuid(), item);
        return true;
    }

    @Override
    public void delete(UUID guid) {
        this.storedItems.remove(guid);
    }
}

The in memory dao uses a Map to hold the MyItem elements. As you can tell, the implementation is straight-forward and doesn’t pull any punches. It does exactly what it needs to do in order for us to test other parts of the system that require the use of the MyDao interface. In order for the other Maven modules to use this test implementation, we have to do a little work in Maven to expose this as a test class. In the POM file relating to the doa-interface module, we add this bit which creates a test jar file.

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Now, using this test jar we can begin to test classes that use the MyDao interface. To use this test jar you modify the POM files for all modules that need access to this code with a dependency with it’s scope set to test.

In our case, we have the MyCommonInterface class which you’ll typically see in applications to give the consumers of the code a unified API to the CRUD operations abstracting away the DAO or DAOs that might make up the data storage of the application.

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.UUID;

/**
 * A common interface to abstract away the various DAOs and allow the consumer of the API one interface to all
 * data.
 */
public interface MyCommonInterface {
    public boolean exists(UUID guid);
    public MyItem get(UUID guid);
    public boolean save(MyItem item);
    public void delete(UUID guid);
}

I’ve also supplied a simple implementation that uses a single DAO,

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.database.dao.MyDao;

import java.util.UUID;

/**
 * A very simple common interface
 */
public class MyCommonInterfaceForOneDao implements MyCommonInterface {
    private final MyDao dao;

    public MyCommonInterfaceForOneDao(MyDao myDao) {
        this.dao = myDao;
    }

    @Override
    public boolean exists(UUID guid) {
        return this.dao.exists(guid);
    }

    @Override
    public MyItem get(UUID guid) {
        return this.dao.get(guid);
    }

    @Override
    public boolean save(MyItem item) {
        return this.dao.save(item);
    }

    @Override
    public void delete(UUID guid) {
        this.dao.delete(guid);
    }
}

You can see that in the constructor, it expects a variable of type MyDao and then uses to perform CRUD operations. In order to properly test this, we need to use the in memory implementation so we don’t have to worry about creating a database, cleaning the database, and all the other database tasks needed just to test this interface. Using the this implementation, we can create a JUnit test class like this:

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.database.dao.MyDao;
import com.laneholloway.unittestingexample.database.dao.MyInMemoryDao;
import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.domain.MyItemImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class MyCommonInterfaceForOneDaoTest {
    private MyCommonInterfaceForOneDao myCommonInterfaceForOneDao;

    @Before
    public void setup() {
        MyDao myDao = new MyInMemoryDao();
        myCommonInterfaceForOneDao = new MyCommonInterfaceForOneDao(myDao);
    }

    @Test
    public void can_save_item() throws Exception {
        MyItem myItem = new MyItemImpl(UUID.randomUUID(),"Test Item");
        myCommonInterfaceForOneDao.save(myItem);
        assertTrue(myCommonInterfaceForOneDao.exists(myItem.getGuid()));
    }

    @Test
    public void can_delete_item() throws Exception {
        MyItem myItem = new MyItemImpl(UUID.randomUUID(),"Test Item");
        myCommonInterfaceForOneDao.save(myItem);
        myCommonInterfaceForOneDao.delete(myItem.getGuid());
        assertFalse(myCommonInterfaceForOneDao.exists(myItem.getGuid()));
    }
}

In the setup method, you can see that MyInMemoryDao is initialized and then injected into the MyCommonInterfaceForOneDao constructor which then allows these simple unit tests to be run verifying the correct operations. And with this, we’ve wrapped up the second section of the code, creating a data access layer that abstracts the database away from the production code and will allow multiple implementations of the data store to be used with minimal issues.

In later articles, I’ll show how to use Spring to simplify these tests and the application itself. Next time, we’ll talk about the business logic and REST layers of the code.

If you have any comments, concerns, or updates I should make to this, let me know in the comments below.

Book Review: How to Light Up A Room

After reading the not-so-hot Who Moved My Cheese?, I picked a book on how to be more charismatic.  I feel I’m a very good socializer and communicator, but at the same time, I also know I can become introverted. So, any book that can provide a tip or a hint is a good thing in my opinion.  There are a few things that this book really has going for it.  First, it’s cheap, at $2.99, it’s hard to really go wrong.  Secondly, it’s short.  I read the entire book in under a few hours.  However, don’t let the fact it’s short put you off.  A short book can be bad or it can be great when it’s to the point.  And that is the third thing I like about the book, it’s to the point.  No building up, just all the information you need to know and none that you don’t.

Now with the introduction, let’s get to the meat of the review — which I’ll keep short and sweet — much like the book itself.  It contains a very small introduction about the 55 tips discussed inside of the book and then jumps right into the tips which are split into six different categories but fall into two major ideas: being upbeat and interacting with people.  Each tip is a simple sentence with a paragraph or two of explanation of how to use the tip in day-to-day interactions.

Chances are you’ll blow through this book in one sitting and to me that is fine.  It saves me from having to read all the other books about building charisma since this book has already summarized the majority of these books.  For the $2.99 that it costs from Amazon.com (or free rental if you have a Kindle device), it’s well worth it.

Book Review: Who Moved My Cheese?

As I’ve been thinking about my career I realize I have seriously neglected the business side for many years.  As part of my quest to learn more about the business side I’ve been finding lists of the supposedly best business books, adding them to my Amazon wish list, finding them at Half Price Books and buying them there, and then reading them.  I know my brother has been doing the same thing and I know if both of us are doing it, there are many other people who are as well.  This is what has gotten me to write a review about the books I’m reading in my copious amounts of free time (haha).  Anyway, this wonderful little ditty Who Moved My Cheese? by Spencer Johnson, M.D. has quite a following both good and bad.  Amazon’s rating (3.3 / 5) seem to show it’s split right down the middle. Some people have said it has changed their life and others view it as trite simplistic mush not even worthy of a first grader.  And, spoiler alert, I fall into the latter camp — I’m not a fan of the book.  I’m glad I got it at HPB for $4.99 cause at it’s $19.95 MSRP it’s a complete rip-off and even at $4.99 I was a little ticked off.  I will give Dr. Johnson props for making a boat load of money off this book of common sense.

I won’t bore you with the fable, but just know it involves Sniff, Scurry, Hem, and Haw as the characters and THE MAZE as the place they live and find Cheese.  If you have just a little bit of imagination you’ll know right away that

  • All four characters find cheese
  • When the cheese disappears Sniff and Scurry leave right away and don’t complain
  • Hem and Haw stick around complaining (obviously) until one realizes they need to be like S&S and find new Cheese in the scary maze
  • Eventually the other one decides to venture out from the original Cheese station and finds everyone else happy

Throw in some nice banal quotes about Cheese (metaphor for money or happiness) and you’ve got a best selling business book.  I’ll save you the money and give some real advice:

  • Things change, get over it
  • No use in crying over the change
  • Be sensitive to changes in the workplace, note what they are and start making plans
  • Always be looking for the next big opportunity
  • Leave on your timeline, not the business’ timeline for you
  • Spend the $5 it’d cost you for this book at HPB on a beer and the $20 it’d cost you for the full thing on a decent meal.  It’d be money better spent.

Running command-line programs from inside Java

I’ve been writing a program for a class I’m taking at school to automate some of the work that had to be done.  I could have written it as a shell script, but I wanted to be more adventurous and write it in Java so it could be run in more than just a Unix environment.  So, as you can guess, I had to do execute the program from the command line.  Normally, you’d do this with the exec method off of the Runtime, however, this causes some problems with permissions.  The way to do execute something from the command line is to use the ProcessBuilder object and it’s dead simple.

List command = new ArrayList();
command.add("file_to_execute");
command.add("option1");
command.add("option2");

ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();

process.waitFor();

As you can tell looking at this simple example, command is a list of String which becomes the command you’d normally type into the command line interface. The processBuilder object sets all the wonderful things up to run an operating system process and when you specify start() it turns it into a Process where you can then wait for all the return value.

Of course, there is a lot more to it than just this, but for my case, all I needed was a quick and dirty command to be run and this did the trick.  You can read more about it on StackOverflow.

Testing in Java: Part I – Introduction

As I’ve alluded to, this is the first article in a series to walk through the process of testing an application for production.  We’ll be making a simple REST interface web application that connects to a back-end database.  It will do some basic CRUD operations and I’ll show how I’d test each layer of this application.  Hopefully, you’ll find some of these techniques useful and able to apply them to your own work.  You can download, fork, or view the entire code base from the GitHub repo.

A typical web application has a few tiers: user interface, business logic, and data access.  In the case of this application I’m following the same idea, but have broken out the objects that are being modified into a domain-objects package inside of the project.  This is where we’ll start this series — talking about the objects and how to test them. I’m going to break the pure TDD-style for this series and write an object first, then write a test :) .

In an application where you’re dealing with objects that the user is performing a CRUD operation upon you’ll want to think about these first.  The initial design would consist of determining what each of these objects are and create an interface and class embodying those concepts.  In our case we have a simple item that consists of a name and a unique identifier.  I’ve named it: MyItem.  Below, you’ll see the interface for MyItem along with a simple default implementation, MyItemImpl.

package com.laneholloway.unittestingexample.domain;

import java.util.UUID;

public interface MyItem {
    public UUID getGuid();
    public String getName();
}
package com.laneholloway.unittestingexample.domain;

import java.util.UUID;

/**
 * A simple default implementation
 */
public class MyItemImpl implements MyItem {
    private final UUID uuid;
    private final String name;

    public MyItemImpl(String itemName) {
        this(UUID.randomUUID(), itemName);
    }

    public MyItemImpl(UUID guid, String itemName) {
        this.uuid = guid;
        this.name = itemName;
    }

    @Override
    public UUID getGuid() {
        return uuid;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) return false;
        if (o instanceof MyItemImpl) {
            MyItemImpl that = (MyItemImpl) o;
            if (that.getGuid().equals(this.uuid) && that.getName().equals(this.name)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

Now that we have the default implementation, we need to have a test for how we want the item to behave within the system. In our case, if the id and the name are the same, the objects are equal. If either is not equal, the objects are not equal. To verify this, we can write a test class using JUnit4. Looking at the code, you’ll notice that I’ve written two of the three tests and I’ve left the last one as an exercise (it really isn’t that hard :) ).

package com.laneholloway.unittestingexample.domain;

import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.domain.MyItemImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Simple tests to show off the MyItemImpl
 */
public class MyItemImplTest {
    private MyItem myItemOne;
    private MyItem myItemTwo;
    private MyItem myItemThree;

    @Before
    public void setup() throws Exception {
        UUID testId = UUID.randomUUID();
        myItemOne = new MyItemImpl(testId, "test");
        myItemTwo = new MyItemImpl(testId, "test");
        myItemThree = new MyItemImpl(UUID.randomUUID(), "test");
    }

    @Test
    public void if_uuid_and_name_are_the_same_items_are_the_same() throws Exception {
        assertTrue(myItemOne.equals(myItemTwo));
    }

    @Test
    public void if_uuids_are_different_the_items_are_different() throws Exception {
        assertFalse(myItemOne.equals(myItemThree));
    }
}

Now, pat yourself on the back, with these three classes you’ve created the object that is being modified by the program and tested it to make sure the implementation behaves as expected.

From here, we will examine the more complicated data access layer, then the business logic, and finally, the REST layer.

As always, if you have any comments, concerns, edits that I should make, let me know in the comments below.