All'università ho preso una lezione in Expert Systems. La lingua insegnata dal libro (CLIPS) era esoterica - Sistemi esperti: Principi e programmazione, quarta edizione . Ricordo di aver passato momenti difficili con questo. Quindi, dopo aver quasi fallito la lezione, avevo bisogno di creare il più fantastico sistema esperto per la mia presentazione finale. Ho scelto di creare un sistema esperto che calcolasse l'analisi del rischio per il portafoglio previdenziale di una persona. In breve, il sistema fornirebbe i servizi normalmente eseguiti dal proprio consulente finanziario. In altre parole, sulla base della personalità, dell'età, dello stato dell'economia macro e di altri fattori, il portafoglio dovrebbe essere conservativo, moderato o aggressivo?
Nell'appendice del libro (o sul CD-ROM), c'era questo programma di esempio approfondito per qualcosa che non era correlato alla mia presentazione. Durante la mia pausa, ho letto e riletto ogni riga di quel programma finché non l'ho capito alla lettera. Anche se non era correlato, ho imparato più di quanto potessi mai leggendo tutti i capitoli. La mia presentazione si è rivelata davvero dannatamente buona e ho ricevuto lodi dal mio professore e dai miei compagni di classe.
Quindi, la morale della storia è ..., comprendendo il codice di altre persone, puoi ottenere maggiori informazioni su un linguaggio / paradigma piuttosto che leggere esempi canonici. Eppure, fino ad oggi, ho problemi con modelli di design di tutti i giorni come il Pattern di fabbrica. Mi piacerebbe sapere se qualcuno potrebbe raccomandare un software open source che mi aiuterebbe a capire i modelli di design della Gang of Four, per lo meno. Ho letto i libri, ma ho problemi a scrivere codice per i concetti nel mondo reale. Forse, studiando il codice utilizzato nelle applicazioni del mondo reale di oggi, potrebbe semplicemente "fare clic".
Mi rendo conto che un software può implementare solo un tipo di modello di progettazione. Ma se il pattern è un'implementazione che ritieni sia utile per l'apprendimento e sai quale pattern cercare all'interno della fonte, spero che tu possa parlarmene.
Ad esempio, lo spazio dei nomi System.Linq.Expressions ha un buon esempio del pattern Visitor. Il client chiama Expression.Accept (new ExpressionVisitor ()), che chiama ExpressionVisitor (VisitExtension), che richiama Expression (VisitChildren), che quindi chiama nuovamente Expression (Accept) - wooah, un po 'contorto. Il punto da notare qui è che VisitChildren è un metodo virtuale. Entrambe le espressioni e le classi derivate da Expression possono implementare il metodo VisitChildren in qualsiasi modo. Ciò significa che un tipo di espressione può eseguire codice completamente diverso da un altro tipo di espressione derivata, anche se la classe ExpressionVisitor è la stessa nel metodo Accept. (Come nota a lato Expression.Accetto è anche virtuale). Alla fine, il codice fornisce un esempio del mondo reale che non si ottiene in nessun libro perché è un po 'confuso.
Per riassumere, se sei a conoscenza di qualsiasi software open source che utilizza un'implementazione del modello di progettazione sei rimasto colpito, per favore elencalo qui. Sono sicuro che aiuterà molti altri oltre a 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)));
}
}