Showing posts with label oop. Show all posts
Showing posts with label oop. Show all posts

Design Patterns - The Command Pattern

There's a lot of knowledge in the book Design Patterns (Gang of Four).  Developers should know the material in there to write efficient and maintainable code, but the book is pretty dry.  I'd say it's quicker and easier to just point curious folks at the Wikipedia article, which sums up more information more quickly, and allows you to dive in if you find one particular bit interesting.

The other day, I was explaining a possible cleaner solution for very nested if/then/else statements; the Command Pattern.  In one variant of this pattern, you represent each "if" choice as an object, and you have a list of smaller objects instead of five hundred lines of hard-to-read/hard-to-maintain code.

Create an interface to tell us what a choice does:

public interface Choice {
    public boolean test(int value);
    public void action(int value);
}

Create a package to put choices into, and create choices that fulfill the interface:
public class LowRangeChoice implements Choice {
    public boolean test(int value) {
        return (value > 10);
    }
    public void action(int value) {
        // Do some action that would be *inside* of the if statement. 
     }
}

Create a List of choices in the constructor of the class with the large if/then/else block:
    List choices = new ArrayList();
    choices.add(new LowRangeChoice());
    ...

And finally, replace the if/then/else block with a short piece of code:
    for (Choice choice : choices) {
        if (choice.test(value)) { 
            choice.action(value);
         }
     }

On something relatively short, this would be overkill and would create a maintenance problem by itself.  However, on something really long - 2000+ lines, for example - this might make an unreadable class into a well ordered selection of small chunks, which seems ideal.

The Command Pattern is also good for quite a few more tasks than just this; a few good examples, mostly pulled from Wikipedia:
  • represent menu items, with each menu item having a test to see if it's been clicked and have an action associated to followup with.
  • represent every user action in the system, and keep previously selected actions on a stack, so that "undo" becomes much easier.
  • if you give a timeRemaining() method to each command, background tasks in the future can be estimated to show a running progress to the user while they wait.

I was going to add into this "how to determine a class is too long", but that seems topic enough for a second post.

Design Patterns

I've been hit with the question "what do you know about design patterns?" more than once, and decided to dig through and refresh some of that on my break today. So, I wound up on Wikipedia, browsing through the Design Patterns article, and pulling a book from the shelf as well.

Design patterns are useful concepts, but my introduction to them was terrible. The definitive text on this one is "Design Patterns: Elements of Reusable Object-Oriented Software", with authors referred to as the "Gang of Four" (GOF). I picked this book up sometime after 2000, after stumbling over an interview question. The book was easily the definitive text in 1995, when it was published, and continues to show up in software engineering curriculum.

There are two problems with it.

  1. The examples are dated. C++ is no longer the dominant OOP language; Java took a big bite, and C# has taken another chunk. C++ is still relevant, but Java and C# devs are going to have problems with pointer-based objects and explicit memory allocation.
  2. The descriptions are *incredibly* verbose. Yes, I realize it's a reference book, but the Iterator pattern is 22 pages of text. That's "an object that iterates over a list". This makes for a fine reference text, but for learning and/or getting an overview of the subject, this book is Not For The Efficient.
The Singleton pattern is seven pages in GOF. "Ensure each class has only one instance, and provide a global point of access for it." Here's the non-thread-safe Java example:

public class Singleton {
// One global instance of the class
static Singleton instance;
// One private constructor, so no other code can call it
private Singleton() { ; }
// One way to get the global instance
public Singleton getInstance
{
if (instance == null) { instance = new Singleton(); }
return instance;
}

// And whatever code may be useful.
}