3

この種のコードを使用して、アプリケーション内の任意のオブジェクトをインスタンス化できるようにしたいと考えています。

SmartForm smartForm = SmartForm.Create("id = 23");
Customer customer = Customer.Create("id = 222");

そのオブジェクトが存在しない場合に Create() が何を返すべきかを議論しています。

  • Create() が空のオブジェクトを返す場合、これは一種の「null パターン」であり、そのオブジェクトをアプリケーションに渡してメソッドを呼び出すことができます。これにより、このモデルを使用したプログラミングが便利で簡単になります。

  • Create() がnullを返す場合、インスタンス化のたびに、オブジェクトが null に等しいかどうかを確認する必要があります。これにより、プログラミングは少し面倒ですが、より明確になります。これに関する問題は、null をチェックするのを忘れた場合、null をチェックしていないことを知らずにアプリケーションが長時間動作し、突然中断する可能性があることです。

  • Create()が例外をスローする場合、基本的には null を返すのと同じですが、インスタンス化ごとに try、next、finally ブロックを作成することでプログラミングがさらに面倒になりますが、さまざまな種類の例外をスローできます (これは可能です)。 null ソリューションを使用すると、UI の深いエラーをより明確に処理できるようになる可能性があるため、これが最も堅牢なソリューションであると考えられますが、try/catch コードの膨張が発生します。

したがって、軽さと堅牢性のトレードオフのようです。その決定のためにあなたが長所または短所を経験したこれらの線に沿って決定を下した経験がある人はいますか?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestFactory234.Models
{
    public class SmartForm : Item
    {
        public string IdCode { get; set; }
        public string Title { get; set; }
        public string Description { get; set; }
        public int LabelWidth { get; set; }

        public SmartForm() { }

        private SmartForm(string loadCode)
        {
            _loadCode = loadCode;
            TryToInstantiateFromDatabase();
        }

        public static SmartForm Create(string loadCode)
        {
            SmartForm smartForm = new SmartForm(loadCode);

            if (!smartForm.IsEmpty())
            {
                return smartForm;
            }
            else
            {
                return null;
            }
        }
    }
}
4

6 に答える 6

6

それは依存します-何かが明らかに間違っているために失敗した場合、例外はプログラミングを容易にします-各呼び出しの周りにtry/catchを記述せず、例外をバブルアップさせます。それを、null/空白の戻り値をチェックしてから例外をスローすることと比較してください。

これはArgumentException、IMO を使用する適切なタイミングのように思えます。

try/catch の「肥大化」を引き起こしていることに気付いた場合は、単に例外を発生させるのではなく、例外をキャッチする必要がある理由を調べてください。

于 2009-06-10T13:26:27.040 に答える
2

空白のオブジェクトが返された場合は、それが有効であると仮定して続行します。または、空白であるかどうかを確認するために、何らかの手の込んだテストを行う必要があります。null が返された場合は、常に null をチェックする必要があります (それで問題ないかもしれません)。これが発生しないようにコードが設計されていると仮定すると、例外がスローされることをお勧めします。これが通常のシナリオである場合は、null を選択することをお勧めします。

于 2009-06-10T13:24:36.500 に答える
2

デフォルトの動作がインスタンスの作成である場合、例外的な動作は作成で失敗することです -> Exception

EmptyObject で何をしますか? あなたはまだそれを渡すことができると言っていますが、これは本当に理にかなっていますか? メソッドを呼び出すと、メソッドは何をしますか?

2 つ目のTryCreate()メソッドを実装する必要があるかもしれません。

私は Exception-variant を実装しますが、必要な動作によって異なります。

于 2009-06-10T13:26:01.410 に答える
1

サンプル コードは「try load from DB」メソッドを呼び出し、Create 規則はCastle ActiveRecordオブジェクトによく似ています。Get/Create データベース操作を分離し、フレームワークが作業を行い、それらの規則に依存できるようにしないのはなぜですか?

[ActiveRecord("Forms")]
public class SmartForm : Item
{
    [PrimaryKey("Id")]
    public string IdCode { get; set; }
    [Property]
    public string Title { get; set; }
    [Property]
    public string Description { get; set; }
    [Property]
    public int LabelWidth { get; set; }
}

このようなインスタンスを取得/作成します

SmartForm entity = ActiveRecordMediator<SmartForm>.Find(1);
SmartForm otherEntity = ActiveRecordMediator<SmartForm>.FindFirst(/* criteria */);

インスタンスを見つける方法は他にもたくさんあります。例外のスロー、null の返し、またはコレクションの場合は空のコレクションに関するActiveRecord のデフォルト は、非常に一貫性があり、適切に実装されていることがわかると思います。

于 2009-06-10T13:41:17.557 に答える
0

作成が失敗することが予測可能であるが、多くのアプリケーション コードがそれが機能することを期待している場合、作成メソッドの 2 つのバージョンを実装する必要があります。一方は成功するか例外をスローし、もう一方は例外をスローします例外をスローする以外の何らかの方法で予想される失敗を示す必要があり、呼び出し元がおそらく予期していない失敗に対してのみ例外をスローします (例: CpuIsOnFireException)。これを行うための一般的なパターンは、TryCreate メソッドが成功を示すブール値を返し、作成された引数を参照渡しの引数に格納することです。私はこのパターンがあまり好きではありません。なぜなら、合否ステータス以外 (つまり、なぜ失敗したのか) を示す手段がないからです。「やってみる」ほうがいいと思います。関数は新しいものまたは null のいずれかを返しますが、失敗の理由を示す by-ref 引数を持っています。このアプローチにより、暗黙的な型付け (C# の "var" キーワードなど) をより適切に使用できることに注意してください。

于 2011-03-22T20:09:04.590 に答える
0

フォーム ファクトリを作成している場合は、文字列ではなく列挙を渡す方が適切です (もちろん、これがプラグイン アーキテクチャを表す場合を除きます)。

于 2009-06-10T13:25:42.207 に答える