Posts Tagged 'c++'

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.

The Wayback Machine : What I Did 10 Years Ago

The Internet is a wonderful thing, but it has a serious flaw. It has a memory. An unrelenting memory, in fact, that seems to remember things that I have long forgotten. Today, it is common knowledge that you should not publish things on the Web that you would not publish in a novel. Ten years ago, though, the Web was as wild as the American Old West. People were doing some pretty wild things.

So, what brought me to think about what I was doing ten years ago? Well, I found out today that Borland finally sold its CodeGear software tools division after two years of trying. Back in 1998, Borland offered a IDE called C++ Builder. When first introduced C++ Builder was the revolutionary step in Windows application development. That tool help me create some tools quickly that Microsoft C++ could never do.

As great as C++ Builder was, it had limit support for DirectX, the relatively new high performance graphics API from Microsoft. Since multimedia was a hobby of mine, I started experimenting with DirectX in C++ Builder. I started a small site using my ISPs personal web pages and thanks to the Wayback Machine, you can see it for yourself and all its splendor.

As my interests in Free Software grew, OpenGL became my dominate graphics environment on Linux. The site was discontinued sometime in late 2000. It seems that the popularity of Free and Open Source software increase, C++ Builder could not compete. Borland later offered a free (as in beer) command line version of the BCC, the same compiler in C++ Builder, but it was the C++ Builder IDE that made it special. I am sad the unfortunate demise of this product. I wish that Borland would have open sourced C++ Builder to let the community decide its fate. It certainly would have been interesting.