Posts Tagged 'programming'

Design Smell: Violating LSP

Sometimes a framework impedes on development so bad, it makes you somewhat angry and feeling helpless. I encountered something today that gives me headaches just thinking about it.

Suppose I have framework in C# 2.0 that models document folder that contains one or more documents. The framework defines an abstract base class, Document:

public abstract class Document {
// Implementation removed.
}

And concrete document types:


public class PurchaseOrder: Document { ... }
public class Quote : Document { ... }
public class Invoice : Document { ... }

And a DocumentFolder class, the have properties for retrieving each of the concrete document types:

public class DocumentFolder {
  public List<PurchaseOrder> PurchaseOrders { get { ... } }
  public List<Quote> Quotes { get { ... } }
  public List<Invoice> Invoices { get { ... }}
}

Let’s say I want to collect every PurchaseOrder, Quote, or Invoice document in a DocumentFolder to perform work on them.  Since all these documents derive from Document, I should be able to create a generic list of type Document and use List<T>.AddRange() to collect  them all.

DocumentFolder folder= LoadFolder(id);
List<Document> docs = new List<Document>();
if (folder.PurchaseOrders != null)
  docs.AddRange(folder.PurchaseOrders);
if (folder.Quotes != null) docs.AddRange(folder.Quotes);
if (folder.Invoices != null) docs.AddRange(folder.Invoices);

Then, use the List<T>.ForEach() operation to perform common work on
my Documents, using an anonymous delegate:

docs.ForEach(new Action<Document>(
  delegate(Document d) {
    DoSomething(d.LineItems);
  }
));

But, I get an error upon compiling. After troubleshooting it, I found that the LineItems property is declared as protected internal, and therefore not available to classes outside the executing assembly:

protected internal List<LineItem> LineItems
{
  get{
    /* Implementation removed. */
  }
}

Each of the three concrete documents override the LineItems property using
the new keyword and calls the base class’ version, effectively crippling
the whole point of having abstract base classes to begin with:

public new List<LineItem> LineItems
{
  get { return base.LineItems; }
}

*sigh*

After pounding my head against my computer,  I accepted this design smell and moved on. This example is a  violation of the Liskov Substitution Principle (LSP), which states in a nutshell:

Methods or functions that use references to base classes must be able
to use objects of derived classes without knowing it.

I could not store a list of the base class, populate the list with instances of the derived class, and perform useful iteration. The workaround resulted in three blocks of iterative code that looks almost alike.  So, I will be addressing this problem with my peers in the near future.  In the meantime, back to coding. Later.

Decorators in Python

A few days ago, I mentioned that I was going to start coding Python again. So, I was looking at Python 2.5 and one of the cooler features that I discovered first were decorators. From what I understand, a decorator wraps behavior of a function or method. It sort of reminds me of auxiliary methods in Common Lisp. A Python function or method can be decorated.

So, I created I quick example that creates a decorator. The simplest decorator is a regular function that accepts a single argument, the function that is being decorated. The decorator returns another function that accepts an argument set and an environment. This is basically a lexical closure. In my decorator, logged, the inner function wrapper is enclosed and wrapper just prints out a message:

def logged(f):
  def wrapper(*args, **kw):
    print "calling %s with args %s." % (f.func_name, args)
    try:
      return f(*args, **kw)
    finally:
      print "done calling %s" % (f.func_name)
  return wrapper

The interesting thing is that wrapper ends up calling the function object passed into the decorator. In this case, the function object is the decorated function add():

@logged
def add(n1, n2):
  return n1 + n2
print add(2, 1)
print add(4, -2)

My simple adder is decorated by the @logged syntax. The Python runtime will execute the decorator and call the closure, passing the arguments from the original function call. When I execute my test program:

$ python decorate.py
calling add with args (2, 1).
done calling add
3
calling add with args (4, -2).
done calling add
2

Awesome! Now, there is more to decorators than meets the eye, and I need to gain more experience using decorators. So, it looks like I am off to a great start.

Choosing A Programming Language

As technology becomes more and more mainstream, there is more younger people wanting to learn how to program. The fundamental question that always gets asked: What language do I learn? There is no simple answer to it. However, if you happen to post this question on a forum, you may get some good advice, some bad advice, or scolded by the elite.

Now, this is not a good start for those who want to learn. So, why is it such a hard question in the first place? From my point of view, it is a matter of circumstance. When I learned my first language, I did not have the Internet at my disposal. So, my choices were dependent on the amount of information that I had available at the time. My first language was assembler. But, it was not for the x86. You see, my first computer was an Atari 800XL, which used a MOS 6502 processor. Although BASIC was built-in, I chose an assembler cartridge that was available at the time. Since my access to information was limited, my choices for learning a programming language was also limited.

Today, information is available instantaneously. When you type in ‘programming’ in your favorite search engine, you would get flooded with a sea of programming languages that every person in the world has a comment about. The plain fact is that people are touting their experiences without considering the person who is asking. So, when I get this question asked to me, I normally respond with a series of questions back.

One of the most important questions that I asked is very direct: What do you want to program? This usually catches people off guard from my experience. However, it is a very concise question that will dictate the path on which the wanna-be programmer will take. With many options out there, choosing the best language can be daunting. My best advice is to use any language that accomplishes your goal: to create something important to you. Research all of the options. Some languages are better than others for your task, but don’t worry about choosing the best do-all language first. Pick any modern language to get your feet wet, you will soon discover whether the language you picked is the right one for you.