web-dev-qa-db-ja.com

コンストラクターで物理リソースを初期化します

オブジェクトが機能するためにリソースが必要なときに、コンストラクターから物理/外部リソースを初期化することは許容できる方法ですか?

たとえば、永続的なメッセージキューをプロキシするオブジェクトを作成し、メッセージキューが物理データベーステーブルであるとします。

テーブルがまだ存在しない場合に物理的にテーブルを作成するべき等コンストラクターを作成することは意味がありますか?

例えば。

IMessageQueue queue = new SQLTableMessageQueue('table_name', dataSource);

おそらく静的ファクトリメソッドの方が適切でしょうか?その場合、テーブルの作成はファクトリメソッドで行われ、コンストラクタはそのような動作をしません。

IMessageQueue queue = SQLTableMessageQueue.create('table_name', dataSource);

適切なアプローチが何であるかよくわかりませんか?私が持っていたもう1つのアイデアは、 リポジトリパターン を使用することでした。

2
plalx

通常、コンストラクターは外部リソースの初期化には使用されません。いくつかの理由があります。

  1. テスト容易性-単体テストを作成するのは非常に難しいでしょう
  2. SRPに準拠するため

メッセージキューは、使用するコンストラクタにいつでも渡すことができます。

class QueueProcessor
{
    private IMessageQueue _queue;

    public QueueProcessor(IMessageQueue queue)
    {
        _queue = queue;
    }
}

はい、ファクトリを使用してキューを作成できます

class QueueFactory
{
    public IMessageQueue CreateMessageQueue
    {
        return new SQLTableMessageQueue('table_name', dataSource);   
    }
}

このアプローチを使用すると、テスト用にメッセージキューを簡単にモックできます。また、コンストラクター内でキューを構築する場合と比較して、SRPに準拠しています。

3

GoogleのC++スタイルガイドでは、 コンストラクターで作業を行う を控えるように求められています。彼らの議論はあなたの言語に当てはまるかもしれないし、当てはまらないかもしれません。トイレの6歳のテスト アドバイス# コンストラクターで作業を行わずにテスト可能なコードを作成する方法についてはまだ保持されています。

オンラインで検索すると、たくさんのことがわかります。 / *プログラマー* / から始めることができます。

0
Jonas Byström