5

In college I took a class in Expert Systems. The language the book taught (CLIPS) was esoteric - Expert Systems: Principles and Programming, Fourth Edition. I remember having a tough time with it. So, after almost failing the class, I needed to create the most awesome Expert System for my final presentation. I chose to create an expert system that would calculate risk analysis for a person's retirement portfolio. In short, the system would provide the services normally performed by one's financial adviser. In other words, based on personality, age, state of the macro economy, and other factors, should one's portfolio be conservative, moderate, or aggressive?

In the appendix of the book (or on the CD-ROM), there was this in-depth example program for something unrelated to my presentation. Over my break, I read and re-read every line of that program until I understood it to the letter. Even though it was unrelated, I learned more than I ever could by reading all of the chapters. My presentation turned out to be pretty damn good and I received praises from my professor and classmates.

So, the moral of the story is..., by understanding other people's code, you can gain greater insight into a language/paradigm than by reading canonical examples. Still, to this day, I am having trouble with everyday design patterns such as the Factory Pattern. I would like to know if anyone could recommend open source software that would help me understand the Gang of Four design patterns, at the very least. I have read the books, but I'm having trouble writing code for the concepts in the real world. Perhaps, by studying code used in today's real world applications, it might just "click".

I realize a piece of software may only implement one kind of design pattern. But, if the pattern is an implementation you think is good for learning, and you know what pattern to look for within the source, I'm hoping you can tell me about it.

For example, the System.Linq.Expressions namespace has a good example of the Visitor Pattern. The client calls Expression.Accept(new ExpressionVisitor()), which calls ExpressionVisitor (VisitExtension), which calls back to Expression (VisitChildren), which then calls Expression (Accept) again - wooah, kinda convoluted. The point to note here is that VisitChildren is a virtual method. Both Expression and those classes derived from Expression can implement the VisitChildren method any way they want. This means that one type of Expression can run code that is completely different from another type of derived Expression, even though the ExpressionVisitor class is the same in the Accept method. (As a side note Expression.Accept is also virtual). In the end, the code provides a real world example that you won't get in any book because it's kinda confusing.

To summarize, If you know of any open source software that uses a design pattern implementation you were impressed by, please list it here. I'm sure it will help many others besides just me.

public class VisitorPatternTest
{

    public void Main()
    {
        Expression normalExpr = new Expression();
        normalExpr.Accept(new ExpressionVisitor());
        Expression binExpr = new BinaryExpression();
        binExpr.Accept(new ExpressionVisitor());
    }
}

public class Expression
{
    protected internal virtual Expression Accept(ExpressionVisitor visitor)
    {
        return visitor.VisitExtension(this);
    }

    protected internal virtual Expression VisitChildren(ExpressionVisitor visitor)
    {
        if (!this.CanReduce)
        {
            throw Error.MustBeReducible();
        }
        return visitor.Visit(this.ReduceAndCheck());
    }

    public virtual Expression Visit(Expression node)
    {
        if (node != null)
        {
            return node.Accept(this);
        }
        return null;
    }

    public Expression ReduceAndCheck()
    {
        if (!this.CanReduce)
        {
            throw Error.MustBeReducible();
        }
        Expression expression = this.Reduce();
        if ((expression == null) || (expression == this))
        {
            throw Error.MustReduceToDifferent();
        }
        if (!TypeUtils.AreReferenceAssignable(this.Type, expression.Type))
        {
            throw Error.ReducedNotCompatible();
        }
        return expression;
    }

}

public class BinaryExpression : Expression
{
    protected internal override Expression Accept(ExpressionVisitor visitor)
    {
        return visitor.VisitBinary(this);
    }

    protected internal override Expression VisitChildren(ExpressionVisitor visitor)
    {
        return CreateDummyExpression();
    }

    protected internal Expression CreateDummyExpression()
    {
        Expression dummy = new Expression();
        return dummy;
    }
}


public class ExpressionVisitor
{
    public virtual Expression Visit(Expression node)
    {
        if (node != null)
        {
            return node.Accept(this);
        }
        return null;
    }

    protected internal virtual Expression VisitExtension(Expression node)
    {
        return node.VisitChildren(this);
    }

    protected internal virtual Expression VisitBinary(BinaryExpression node)
    {
        return ValidateBinary(node, node.Update(this.Visit(node.Left), this.VisitAndConvert<LambdaExpression>(node.Conversion, "VisitBinary"), this.Visit(node.Right)));
    }
}
3
  • If this post doesn't belong in this forum, please let me know which of the stack exchange sites the question/discussion might be appropriate. I just learned of the "Programmers" site. This is my first post here.
    – John C
    Commented Sep 20, 2012 at 6:47
  • 4
    Sorry Fathom, but Stack exchange isn't a forum and doesn't work like one. We are not here to participate in a discussion, we are here to help answer practical, answerable questions based on actual problems that you face. Do you have an actual question that we can you help with?
    – Mark Booth
    Commented Sep 20, 2012 at 10:12
  • Ok, I got it. I didn't understand the function of the forum. I'll ask a question next time.
    – John C
    Commented Sep 26, 2012 at 3:26

4 Answers 4

3

I suggest to study the xUnit Framework along with the implementation. It's a mature product with clean architecture and extremely tidy source code. Also it comes with a full pack of unit tests, so you can achieve several goals at once: deeply learning a unit testing framework, looking at the examples of applied design patterns, and seeing how to write tests for them.

3
  • Haha...Yes! See my comment @Baboon above. I agree that unit tests help you realize the patterns that emerge.
    – John C
    Commented Sep 26, 2012 at 3:43
  • Hmmm...xUnit appears to be very different from NUnit, which is what I'm using for TDD. I visited the xUnit.net page, but there isn't any documentation yet. Is there a blog page that you would recommend? Thanks.
    – John C
    Commented Sep 26, 2012 at 3:51
  • @@Bazurbat I've re-read your answer and will check out the source code to see if I can learn something from it's implementation. Will get back to you and post something informative about any patterns I learn reading it. Also, a testing framework seems easy to understand and is probably an excellent learning tool. Thanks for the suggestion!!
    – John C
    Commented Sep 26, 2012 at 4:15
10

It looks like you would like to understand the design patterns in a practical sense with examples. I suppose a good book with real-life examples will help you.

In addition, it looks like there are some tight coupling in the code. I would look at SOLID design principles (like single responsibility principle) to design my code to loosely coupled and interchangeable/replaceable pieces.

As a suggestion, you may start with a highly recommended book of design patterns, Head First Design patterns is really good book to consider. I love this book.

2
  • 3
    That is an awesome book! One of my favorites
    – user2528
    Commented Sep 20, 2012 at 12:54
  • @ElYusubov Yes, Head First Design Patterns is an awesome book. I've read it. And I'm reading Head First Object Oriented Analysis now. I should probably re-read the chapter on the factory pattern. Thanks for your answer. Is there any open source code that implements the factory pattern that you really were impressed with?
    – John C
    Commented Sep 26, 2012 at 3:30
4

The developers of SharpDevelop actually wrote a book about it, and it discusses the design patterns used: Dissecting a C# Application - Inside SharpDevelop

3
  • Scott, I've downloaded the book, and it's an impressive 500+ pages. However, I don't understand what you think I will learn from it. The first chapter shows how to develop in an antiquated IDE. I'm all for not using Visual Studio if the IDE is better, but I don't see how another IDE will help me program better. I've looked in the table of contents, and I do not see a chapter on design patterns. It may be that this book will help me. Can you tell me specifically where to look? Or are you saying, that because it is an open source IDE, that I should look at the code to see the patterns?
    – John C
    Commented Sep 26, 2012 at 4:03
  • 1
    @FathomSavvy - the book explains how they built the first version of SharpDevelop, and during that development they used several design patterns. In fact, early in the book I seem to recall a whole chapter devoted to the design patterns they used extensively during the development. In particular, the Strategy Pattern, and the Memento Pattern, among others. Commented Oct 2, 2012 at 12:23
  • The link above has expired. Use this link. web.archive.org/web/20070120003019/http://www.apress.com/free/…
    – John C
    Commented Dec 14, 2013 at 11:08
3

You got it upside down, like many students/people fresh out of school, design patterns shine as a way to become a great developer.
You couldn't be more wrong, this leads to over-engineering real fast, and that's bad programming.

You don't start by thinking which design pattern should be used for this or that, you start writing code, and as you refactor, patterns emerge. May it be reusing some components, components having similar behavior, you name it.

Then as you gain experience, you'll be able to forsee that a particular pattern is going to emerge, and can plan ahead by using a design pattern from day one.

Design patterns themselves, as of GoF's definition at least, are a way for programmers to be able to talk and share about experience by using words that everyone understands (i.e: Factory pattern).
However, they are not an international way of handling a particular problem, and they should not be blindly used.

My advice, is that you should get your hands dirty, get some experience, and reflect on it: "how could I have made this code better". And whenever you can/have the time/touch a poorly designed code, refactor!

3
  • I'm just wrapping my hands around Test Driven Development (I've done it for my latest project - and I'm learning using this website called the Art of Unit testing - artofunittesting.com). The paradigm requires that you refactor frequently. I agree that as you start to design using tests, you see patterns emerge. I've gotten my hands dirty plenty, but not using TDD, and never have I written better code than I have using TDD. I should get my hands dirty more writing tests first. Do you agree? Programming off the cusp lead me to this question.
    – John C
    Commented Sep 26, 2012 at 3:38
  • FYI... artofunittesting.com has videos of a teacher showing a student how to use test driven development to create a game of Go. It's weird to watch because the teacher doesn't understand the game of Go and confusion emerges, but because both student and teacher make so many mistakes, it is very informative watching them correct themselves.
    – John C
    Commented Sep 26, 2012 at 3:42
  • Whatever floats your boat, as long as you keep on programming something! It doesn't matter what you put on your hands, just keep 'em dirty ;) Commented Sep 26, 2012 at 8:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.