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)));
}
}