web-dev-qa-db-ja.com

オブジェクトの適切なインスタンス化に失敗する可能性のあるコンストラクターの作成方法

失敗する可能性のあるコンストラクタを作成する必要がある場合があります。たとえば、次のようなファイルパスでオブジェクトをインスタンス化したいとします。

obj = new Object("/home/user/foo_file")

パスが適切なファイルを指している限り、すべて問題ありません。しかし、文字列が有効なパスではない場合、問題が発生します。しかし、どうやって?

あなたは出来る:

  1. 例外を投げる
  2. nullオブジェクトを返す(プログラミング言語でコンストラクタが値を返すことが許可されている場合)
  3. 有効なオブジェクトを返しますが、そのパスが正しく設定されなかったことを示すフラグが付いています(ugh)
  4. 他?

さまざまなプログラミング言語の「ベストプラクティス」では、これを異なる方法で実装すると思います。たとえば、ObjCは(2)を好むと思います。しかし、(2)C++で実装することは不可能であり、コンストラクターは戻り型としてvoidを持たなければなりません。その場合(1)を使用していると思います。

選択したプログラミング言語で、この問題の処理方法を示し、その理由を説明できますか?

11
garageàtrois

ダーティーな作業を行うためにコンストラクターに依存することは決して良いことではありません。さらに、明示的に記述されたドキュメントがない限り(そしてクラスのユーザーがそれを読んだ、またはそう言われていない限り)、コンストラクタで作業が行われるかどうかは、別のプログラマにとってnclearでもあります。 。

例(C#の場合):

_public Sprite
{
    public Sprite(string filename)
    {
    }
}
_

ユーザーがすぐにファイルをロードしたくない場合はどうなりますか?ファイルのオンデマンドキャッシュを実行したい場合はどうなりますか?彼らはできません。 _bool loadFile_引数をコンストラクターに配置することを考えるかもしれませんが、これにより、今のようにこれが厄介になりますstillファイルをロードするためにLoad()メソッドが必要です。

現在のシナリオを考えると、これを行うには、クラスのユーザーにとってより柔軟で明確になります。

_Sprite sprite = new Sprite();
Sprite.Load("mario.png");
_

または代わりに(リソースのようなもの):

_Sprite sprite = new Sprite();
Sprite.Source = "mario.png";
Sprite.Cache();

// On demand caching of file contents.
public void Cache()
{
     if (image == null)
     {
         try
         {
             image = new Image.FromFile(Source);
         }
         catch(...)
         {
         }
     }
}
_
8
Nick Bedford

Javaでは、例外を使用するか、ファクトリパターンを使用して、nullを返すことができます。

Scalaでは、ファクトリーメソッドからOption [Foo]を返すことができます。これはJava=でも機能しますが、より面倒です。

7
Kim

例外をスローします。

返すことができる場合は、nullをチェックする必要があります(チェックされません)。

これがチェック例外の対象です。失敗するかもしれませんね。呼び出し元はこれを処理する必要があります。

3
Tim Williscroft

C++では、コンストラクターを使用してクラスのメンバーを作成/初期化します。

正解はありませんこの質問に。しかし、私がこれまで観察してきたことは、ほとんどの場合、この処理方法を選択するクライアント(またはAPIを使用するユーザー)です。

場合によっては、オブジェクトがコンストラクタで必要とする可能性のあるすべてのリソースを割り当て、何かが失敗した場合は例外throw例外が発生する(オブジェクトの作成が中止される)か、コンストラクタでそれを行わない場合があります。作成が常に成功することを確認し、一部のメンバー関数が実行するこれらのタスクを残します。

動作を選択するのはあなた次第です例外はエラーを処理するためのデフォルトのC++の方法であり、可能な場合はそれらを使用する必要があります。

3
karlphillip

パラメータなしで、または絶対に失敗しないことが確実なパラメータのみでオブジェクトをインスタンス化してから、例外を安全にスローしたり、必要なことを行うことができる初期化関数またはメソッドを使用することもできます。

1
gablin