web-dev-qa-db-ja.com

デザインパターンの学習に役立つC#オープンソースソフトウェア

大学では、エキスパートシステムのクラスを受講しました。本が教えた言語(CLIPS)は難解でした- エキスパートシステム:原則とプログラミング、第4版 。苦労したことを覚えています。それで、クラスにほとんど失敗した後、私は私の最終的なプレゼンテーションのために最も素晴らしいエキスパートシステムを作成する必要がありました。私は、個人の退職金ポートフォリオのリスク分析を計算するエキスパートシステムを作成することにしました。要するに、このシステムは通常、自分の財務顧問が行うサービスを提供することになります。言い換えれば、性格、年齢、マクロ経済の状態、およびその他の要因に基づいて、ポートフォリオは保守的、中程度、または積極的である必要がありますか?

この本の付録(またはCD-ROM)には、私のプレゼンテーションとは無関係の詳細なサンプルプログラムが含まれていました。休憩時間に、私はそのプログラムのすべての行を読み、その内容を理解できるまで読み直しました。関係はありませんでしたが、すべての章を読むことで、これまで以上に多くのことを学びました。私のプレゼンテーションは非常に素晴らしいものであることがわかり、教授やクラスメートから賞賛を受けました。

したがって、この話の教訓は...他の人のコードを理解することで、標準的な例を読むよりも言語/パラダイムについてより深い洞察を得ることができます。それでも、今日に至るまで、Factory Patternなどの日常のデザインパターンに問題があります。少なくとも、Gang of Fourのデザインパターンを理解するのに役立つオープンソースソフトウェアを誰かが推奨できるかどうか知りたいのですが。本を読みましたが、現実世界の概念のコードを書くのに苦労しています。おそらく、今日の実際のアプリケーションで使用されているコードを研究することで、「クリック」するだけかもしれません。

1つのソフトウェアで1種類のデザインパターンしか実装できない場合があることに気付きました。しかし、パターンが学習に適していると考える実装であり、ソース内で探すべきパターンがわかっている場合は、それについて教えていただければ幸いです。

たとえば、System.Linq.Expressions名前空間には、訪問者パターンの良い例があります。クライアントは、Expression.Accept(new ExpressionVisitor())を呼び出します。これは、ExpressionVisitor(VisitExtension)を呼び出し、Expression(VisitChildren)を呼び出し、次に、Expression(Accept)を再度呼び出します。ここで注意すべき点は、VisitChildrenは仮想メソッドであることです。 Expressionと、Expressionから派生したクラスの両方で、VisitChildrenメソッドを任意の方法で実装できます。つまり、ExpressionVisitorクラスがAcceptメソッドで同じであっても、あるタイプの式は、別のタイプの派生式とは完全に異なるコードを実行できます。 (補足として、Expression.Acceptも仮想です)。結局のところ、このコードは実際の例を提供しているので、ちょっとわかりにくいので本には載っていません。

要約すると、印象に残った設計パターンの実装を使用するオープンソースソフトウェアを知っている場合は、ここにリストしてください。私だけでなく、他の多くの人の役に立つと確信しています。

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)));
    }
}
5
John C

xUnit Framework を実装とともに検討することをお勧めします。クリーンなアーキテクチャと非常に整頓されたソースコードを備えた成熟した製品です。また、ユニットテストのフルパックが付属しているため、ユニットテストフレームワークを深く学習し、適用された設計パターンの例を調べ、それらのテストを作成する方法を確認することで、一度にいくつかの目標を達成できます。

3
Oleg Kolosov

例を用いて実用的な意味でデザインパターンを理解したいと思います。実際の例を含む優れた本が役立つと思います。

さらに、コードには緊密な結合があるようです。私はSOLID設計原則(単一責任の原則のような)を見て、疎結合で交換可能/交換可能な部分にコードを設計します。

提案として、デザインパターンの非常に推奨される本Head First Designから始めることができますpattern は、検討するのに最適な本です。私はこの本が大好きです。

10
Yusubov

SharpDevelop の開発者は実際にそれについて本を書いており、使用されている設計パターンについて説明しています: C#アプリケーションの分析-SharpDevelopの内部

4
Scott Whitlock

多くの生徒や学校を卒業したばかりの人のように、デザインパターンは優れた開発者になるための方法として輝いています。
あなたはもっと間違っていることはできません、これは実際に速く過剰設計することにつながります、そしてそれは悪いプログラミングです。

このために使用するデザインパターンを考えることから始めるのではなく、コードの記述を開始します。リファクタリングすると、パターンが出現します。いくつかのコンポーネントを再利用している可能性があります。同様の動作をするコンポーネントは、あなたがそれに名前を付けます。

その後、経験を積むと、特定のパターンが出現することを予測でき、初日からのデザインパターンを使用して事前に計画を立てることができます。

デザインパターン自体は、少なくともGoFの定義では、プログラマーが誰もが理解できる言葉(つまり、ファクトリーパターン)を使用して話し、経験について共有できる方法です。
ただし、これらは特定の問題を処理するための国際的な方法ではないため、盲目的に使用しないでください。

私のアドバイスは、あなたは手を汚し、経験を積んで、それに反省する必要があるということです:「このコードをより良くすることができたでしょう」。そして、あなたができる/時間を持っている/不十分に設計されたコードに触れるときはいつでもrefactor!

3
Louis Kottmann