Archive for the ‘OO design’ Category

Scala exercise 3: decorator and composite design patterns

Saturday, October 16th, 2010

Introduction

This is the third  exercise in my Scala exercises series. If you haven’t seen it before, you may want to start from exercise 1: template method and exercise 2: observer design pattern. Below is exercise 3: decorator and composite design patterns.

Problem: In most UI frameworks including JSF, Wicket or Swing, you will need to provide a callback/listener object to handle requests from the user. Typically in such a callback, if there are some errors, you’d like to display a specific error message instead of propagating it to the framework, otherwise the framework would simply display a generic error to the user.

To hand code such a callback, you may do it like:

new Callback() {
  def onCallback(ev: Any) {
    try {
      //perform the business logic here
    } catch {
      case e: LoginException => {
        //assuming that error() will display the error
        error("failed to login")
      }
      case e: SQLException => {
        error("error accessing the database")
      }
    }
  }
}

The problem with this approach is that there is a lot of boilerplate code there, while most usually we only want to say for exception class E1, display some error message M1:

new ErrorHandlingCallback(
  //classOf[Foo] is the same as Foo.class in Java
  classOf[LoginException], "failed to login",
  classOf[SQLException], "...") {
  def performBusinessLogic(ev: Any) {
      //perform the business logic here
  }
}

But what if you’d like to extract some information from the exception and include it into the error message or would like to do something special? Then, ideally, you should be able to specify a function as the error handler:

new ErrorHandlingCallback(
  classOf[LoginException], "failed to login",
  classOf[SQLException], "...",
  (e: Exception) => doSomething(e)) {
  def performBusinessLogic(ev: Any) {
      //perform the business logic here
  }
}

Finally, you should be able to pre-define an object to handle the commonly seen exceptions:

//ideally you should be able to "add" the error
//handlers together to get a compound error
//handler
val defaultErrorHandler =
  (classOf[IOException], "I/O error") +
  (classOf[Exception], "Unknown catch all error")

new ErrorHandlingCallback(
  classOf[LoginException], "failed to login",
  ...,
  defaultErrorHandler) {
  def performBusinessLogic(ev: Any) {
      //perform the business logic here
  }
}

Your task is to complete the code below and create the other necessary classes as needed:

trait Callback {
  def onCallback(ev: Any)
}

abstract class ErrorHandlingCallback(errorHandler: ErrorHandler) extends Callback {
  //overload the constructor to take multiple error handlers (the star does that)
  def this(errorHandlers: ErrorHandler*) = ...

  def performBusinessLogic(ev: Any)

  def onCallback(ev: Any) {
    ...
  }
}

object ErrorHandlerUtil {
  //allow you to use a function as an error handler
  implicit def fromFunc(f: Exception => Boolean): ErrorHandler = ...
  //allow you to use a pair (error class, error message) as an error handler
  implicit def fromPair(p: (Class[_ <: Exception], String)): ErrorHandler = ...
}

Then, the following code should compile and run:

object ErrorHandlerTest {
  //in order to use the implicit conversion methods, you
  //must import these objects so that those methods can
  //be invoked without a prefix.
  import ErrorHandlerUtil._

  def main(args: Array[String]) {
    //assume that this is the default error handler in this context
    //classOf[Foo] is the same as Foo.class in Java
    val defaultErrorHandler = (classOf[IOException], "I/O error") + (classOf[Exception], "Unknown catch all error")
    //create a decorator to handle additional errors
    val decorator = new ErrorHandlingCallback(
      //convert a pair to an error handler
      (classOf[IndexOutOfBoundsException], "index out of bound"),
      //ditto
      (classOf[NullPointerException], "hit a null pointer"),
      //you can define a custom error handler using a function to, say,
      //access the info in the exception (not just its class).
      (e: Exception) => if (e.getMessage.contains("xyz")) {
        println(e.getMessage)
        true //indicate that it has been handled
      } else false,
      //specify the default error handler here
      defaultErrorHandler) {
      def performBusinessLogic(ev: Any) {
        println("called")
        ev match {
          //do nothing. No error.
          case "foo" =>
          //try to access the 100th element of an array which has only 3 elements
          case "bar" => Array[Int](1, 2, 3).apply(100)
          //Try to call a method on null
          case "baz" => null.equals("oops!")
          //throw a custom exception
          case "baz2" => throw new RuntimeException("I am xyz!")
          //divided by zero (something unexpected to test the ultimate fallback)
          case "baz3" => 100 / 0
        }
      }
    }
    decorator.onCallback("foo")
    decorator.onCallback("bar")
    decorator.onCallback("baz")
    decorator.onCallback("baz2")
    decorator.onCallback("baz3")
  }
}

Try to do it now! Then, click here to see the answer.

Scala exercise 2: observer design pattern

Sunday, October 10th, 2010

Introduction

This is the second exercise in my Scala exercises series. If you haven’t seen it before, you may want to start from exercise 1: template method. Below is exercise 2: observer design pattern.

Problem: Complete a Scala trait Observed (shown below) to represent the subject being observed and the Scala trait Observer to represent an observer. The Observed object allows one or more Observers to register with it. Later, it can fire an event and notify all such Observers. The code is like (where E is the type of the event to be fired):

trait Observed[E] {
  def addObserver(o: Observer[E]) ...
  def notifyObservers(ev: E) ...
}

trait Observer[E] {
  def eventOccurred(ev: E)
}

Then use these traits to implement Java bean “bounded properties”, e.g., to allow others to get notified when properties of a Book instance is changed:

//Let others observe changes to its properties
case class Book(var title: String, var price: Double) extends Observed[PropertyChangeEvent] {
  def setTitle(title: String) {
    val oldTitle = this.title
    this.title = title
    //Notify the observers
    ...
  }
  def setPrice(price: Double) {
    val oldPrice = this.price
    this.price = price
    //Notify the observers
    ...
  }
}

//A sample observer class
class Foo extends Observer[PropertyChangeEvent] {
  //Just print some info after a property has been changed
  def eventOccurred(ev: PropertyChangeEvent) = {
    printf("Foo: %s of %s has changed from %s to %s\n", ev.getPropertyName, ev.getSource, ev.getOldValue, ev.getNewValue)
  }
}

object BeanTest {
  def main(args: Array[String]) {
    val b1 = new Book("Scala programming", 35.95)
    val foo = new Foo
    b1.addObserver(foo) //Register the observer
    b1.setTitle("Thinking in Scala")  //foo should get an event
    b1.setPrice(39.95) //ditto
    b1.setTitle("Effective Scala") //ditto
  }
}

The above code should print:

Foo: title of Book(Thinking in Scala,35.95) has changed from Scala programming to Thinking in Scala
Foo: price of Book(Thinking in Scala,39.95) has changed from 35.95 to 39.95
Foo: title of Book(Effective Scala,39.95) has changed from Thinking in Scala to Effective Scala

Try to do it now! Then, click here to see the answer.

Scala exercise 1: template method design pattern

Sunday, October 3rd, 2010

Introduction

As part of my studying with Scala, I have tried to find some exercises to do but most are either too simple or too “academic”. So, I decided to create a series of Scala exercises to implement the well known design patterns in an industrial context. Here is the first one: template method.

Problem: Create a Scala class JdbcTemplate that has two template methods: execute() and load(). They will execute a SQL statement and load the query results using JDBC respectively. The methods should open and close the connection, create and close the statement and etc. so that the caller doesn’t need to worry about those. For example, the client could use your code like this:

object Test {
  def main(args: Array[String]) {
    Class.forName("org.h2.Driver")
    val t = new JdbcTemplate
    val ds = () => DriverManager.getConnection("jdbc:h2:~/test")
    t.execute(ds, "drop table products if exists")
    t.execute(ds, "create table products (id long primary key, name varchar(128))")
    val insertSql = "insert into products values(?, ?)"
    t.execute(ds, insertSql, List(100, "p1")) //the list is the parameters
    t.execute(ds, insertSql, List(101, "p2")) //ditto
    val ps = t.load[Product](ds, "select * from products", Nil,
      { //this function maps a record into an object
        (rs) => new Product(rs.getLong("id"), rs.getString("name"))
      })
    println(ps)
  }
}

//make it a case class so that it can be printed to the console nicely
case class Product(val id: Long, val name: String) {
}

To make it run, you need to include the h2 database into your classpath. If you use Maven, just add the following to pom.xml:

       <dependency>
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
             <version>1.2.143</version>
       </dependency>

Note that I am not suggesting that you do this in production code; you’d probably want to use an ORM framework.

Click here to see the answer.

Better name for ModelAndView in Spring MVC?

Sunday, April 25th, 2010

I am always skeptical about names containing the word “And” as they aren’t expressing a single concept. What about the ModelAndView class in Spring MVC? It is something the controller returns to indicate what view to render and optionally provide models (data) to be displayed in that view.

What is the single concept here? I think it may be called PresentationIngredients as the view and the models will be used to create the presentation.

What’s your take? Or do you think ModelAndView is already good enough? Why not many people raised the problem before?

Refactoring challenge: finding a better name

Sunday, April 18th, 2010

A common code smell is that a name containing the word “And”. For example, consider class below:

	private final static class ObjectAndGetSetter
	{
		private final IGetAndSet getAndSetter;
		private final Object value;
		...
		//getters and setters
	}

	public static interface IGetAndSet
	{
		public Method getGetter();
		public Method getSetter();
	}

Both the IGetAndSet and ObjectAndGetSetter names contain the word “And”. Why is it a bad thing? Because there are multiple concepts in the name (e.g., the concepts of getter and setter in IGetAndSet), indicating that the single concept has not been spelled out yet. For this case, for IGetAndSet, I think the single concept is “property”. For ObjectAndGetSetter, the single concept is “property of a given instance”. So, I’d change the code as:

	private final static class InstanceProperty
	{
		private final IProperty property;
		private final Object instance;
		...
		//getters and setters
	}

	public static interface IProperty
	{
		public Method getGetter();
		public Method getSetter();
	}

Now the challenge: in Spring MVC there is a ModelAndView class:

public class ModelAndView {
	/** View instance or view name String */
	private Object view;

	/** Model Map */
	private ModelMap model;
	...
}

How do you rename it? Or is it good enough? Post your suggestions as comments.