Jeff's Blog

Musings about software development, Java, OO, agile, life, whatever.


Monday, October 24, 2005 
Database TDD Part 9: Single Responsibility Principle

The User class is still doing too much by managing its own persistence. Following the SRP, I've redesigned the classes so that the User class only manages user information, and a new class, UserAccess, persists users. In the new design, the User class knows nothing about the persistence mechanism whatsoever. This does change the client interface, mind you.

UserTest

package domain;

import junit.framework.*;

public class UserTest extends TestCase {
   static final String name = "a";
   static final String password = "b";
   private User user;

   protected void setUp() {
      user = new User(name, password);
   }

   public void testCreate() {
      assertEquals(name, user.getName());
      assertEquals(password, user.getPassword());
   }
}

User

package domain;

public class User {
   private String name;
   private String password;

   public User(String name, String password) {
      this.name = name;
      this.password = password;
   }

   public String getName() {
      return name;
   }

   public String getPassword() {
      return password;
   }
}

UserAccessTest

package domain;

import junit.framework.*;

public class UserAccessTest extends TestCase {
   public void testPersist() {
      final String name = "a";
      final String password = "b";

      User user = new User(name, password);
      UserAccess access = new UserAccess();
      access.save(user);
      User retrievedUser = access.find(name);
      assertEquals(name, retrievedUser.getName());
      assertEquals(password, retrievedUser.getPassword());
   }
}

UserAccess

package domain;

import java.util.*;

import persistence.*;
import util.*;

public class UserAccess {
   private static final String TABLE_NAME = "userdata";
   private static String[] columns = { "name", "password" };

   public void save(User user) {
      new JdbcAccess().execute("insert into " + TABLE_NAME + " ("
            + createColumnList()  + ") values ("
            + createValuesList(user) + ")");
   }

   private String createValuesList(User user) {
      Transformer ticWrapper = new Transformer() {
         public String transform(String input) {
            return StringUtil.wrap(input, '\'');
         }
      };
      return StringUtil.commaDelimit(new String[] { user.getName(),
            user.getPassword() }, ticWrapper);
   }

   public User find(String nameKey) {
      JdbcAccess access = new JdbcAccess();
      List<String> row = access.executeQuery(String.format(
            "select " + createColumnList() + " from " + TABLE_NAME + " where name = '%s'",
            nameKey));
      return new User(row.get(0), row.get(1));
   }

   private static String createColumnList() {
      return StringUtil.commaDelimit(columns);
   }
}
A minor refactoring followed. I don't recall how I got there, but my use of the String format method (introduced in J2SE 5.0) is less than ideal. The save and find methods can be cleaned up so that the SQL strings are much easier to read.
   public void save(User user) {
      String sql = String.format("insert into %s (%s) values (%s)", TABLE_NAME,
            createColumnList(), createValuesList(user));
      new JdbcAccess().execute(sql);
   }
...
   public User find(String nameKey) {
      String sql = String.format("select %s from %s where name = '%s'",
            createColumnList(), TABLE_NAME, nameKey);
      JdbcAccess access = new JdbcAccess();
      List<String> row = access.executeQuery(sql);
      return new User(row.get(0), row.get(1));
   }
So far, nothing earth shattering. The more interesting challenge is up next: we have to persist objects of a second type. The imminent redundancy should already be apparent. How will we keep UserAccess and whatever new access class from looking almost exactly alike?


Comments: Post a Comment

Links to this post:

Create a Link



<< Home

RSS Feed (XML)

Archives

February 2004   March 2004   May 2004   September 2004   October 2004   January 2005   February 2005   September 2005   October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   June 2006   August 2006   January 2007   February 2007   March 2007   April 2007   September 2007   October 2007   November 2007   December 2007   January 2008  

This page is powered by Blogger. Isn't yours?