6

状況は次のとおりです。やりすぎているクラスがあります。主に構成情報にアクセスするためのものですが、データベース接続もあります。これはシングルトンとして実装されているため、ほとんどのコードが非常に緊密に結合されているため、単体テストも困難になります。これは、インポート時の依存関係を作成するため (Python でこれを行っています)、さらに問題が大きくなります。これは、特定のモジュールを特定の順序でインポートする必要があることを意味します。理想的には、これを 2 つのクラスに分割し、非シングルトンにしたいと考えています。

幸いなことに、私の雇用主は、この種のテストが優れているという事実を受け入れており、コードがよりテストしやすくなるのであれば、このような変更を喜んで許可してくれます。しかし、私がそれに多くの時間を費やすことを彼らが喜んで許してくれるかどうかは疑わしい. そして、過激になりすぎるのではなく、これを段階的に修正したいと思います。

したがって、ここには 3 つの選択肢があります。

  1. 構成オブジェクトを (シングルトン) 構成オブジェクトと (非シングルトン) データベース オブジェクトに分割します。これにより、少なくともインポート時の依存関係としてデータベースを削除できます。
  2. 構成オブジェクトを非シングルトンにして、それを必要とするオブジェクトに渡します。これは私たちの短期的なニーズによりよく対応していると思いますが、それにはかなり時間がかかると思います.
  3. あなたがあなたの答えで提案することを私が考えていなかった何かをしてください。:-)

それで、私は何をしますか?

4

4 に答える 4

5

コードを見ずに知るのは難しいですが、あなたの言うことを実行してみませんか? 最初にステップ 1 を実行し、データベースを分割します。

それが速い場合は、戻ってください。これで、2 つではなく、シングルトンであることをやめる小さなオブジェクトが 1 つだけになりました。したがって、ステップ 2 はより速くなるはずです。または、この段階で、シングルトンからリファクタリングできる他のコードが表示される場合があります。

シングルトンに含まれるものを、それがなくなるまで段階的に削減できれば幸いです。どの段階でも、膨大な時間税を支払う必要はありません。

たとえば、構成の一部が独立している場合、構成の一部を一度にシングルトンにすることができます。おそらく、ファイル構成のリファクタリング中にGUI構成がシングルトンを残した、または同様のものでしたか?

于 2009-07-03T15:41:19.237 に答える
5

あなたは順調に2つのクラスに分かれていると思います。必要に応じて、ファクトリを使用してデータベース コンテキスト/接続を作成することを検討してください。このようにして、オブジェクトの存続期間中単一の接続を維持するのではなく、必要に応じて作成/破棄される作業エンティティの単位として接続を扱うことができます。YMMVだけど。

構成に関しては、これはシングルトンが正しい選択であることがわかった 1 つのケースです。単体テストが難しいという理由だけで、必ずしもダンプするわけではありません。ただし、インターフェイスを実装するためにビルドすることを検討することをお勧めします。次に、依存性注入を使用して、テスト中にインターフェイスのモック インスタンスを提供できます。実稼働コードは、挿入された値が null の場合にシングルトン インスタンスを使用するか、シングルトン インスタンスを挿入するように構築されます。または、プライベート メソッドを介して再初期化できるようにクラスを構築し、セットアップ/ティアダウン テスト メソッドでこれを呼び出して、テストに適切な構成があることを確認することもできます。私は後者の実装よりも前者を好みますが、インターフェイスを直接制御できない場合にも使用しました。

段階的に変更を加えることは、間違いなく進むべき道です。可能であれば、現在の機能をテストでラップし、それらのテストが変更後もパスすることを確認すること (もちろん、変更を直接処理するものではありません) は、他のコードを壊していないことを確認するための良い方法です。 .

于 2009-07-03T15:48:43.747 に答える
2

オプション 1 は、私がすべてのアプリで行っていることです。構成オブジェクト シングルトンと、オンデマンドで作成または挿入されたデータベース オブジェクトです。

構成オブジェクトをシングルトンとして持つことは、常に私にとって完璧に適合しています。構成ファイルは 1 つしかなく、アプリケーションの起動時に常に読み取りたいと考えています。

于 2009-07-03T15:43:00.530 に答える
2

私はPythonをまったく知らないので、疑似コードが理にかなっていることを願っています...

シングルトンの責任が小さくなるように、最初にオブジェクトを2つの部分に分割し、次に残りの構成シングルトンを取得して通常のクラスに変更します(2番目の提案を実行するかのように)。

そこまで到達したら、構成クラスのメソッドを公開する新しいラッパー シングルトンを作成します。

class ConfigurationWrapper : IConfigurationClass 
{
    public static property ConfigurationWrapper Instance;

    public property IConfigurationClass InnerClass;

    public method GetDefaultWindowWidth()
    {
        return InnerClass.GetDefaultWindowWidth();
    }

    etc...
}

アプリケーションが最初に行うことは、ConfigurationClass のインスタンスをラッパーに挿入することです。

ConfigurationClass config = new ConfigurationClass()
ConfigurationWrapper.Instance.InnerClass = config;

最後に、現在シングルトンに依存しているクラスをラッパー シングルトンに移動できます (これは迅速な検索と置換である必要があります)。これで、クラスを 1 つずつ変換して、コンストラクターを介して構成オブジェクトを取り込み、ステージ 2 を完了できます。時間がない場合は、ラッパー シングルトンを使用できます。それらをすべて移動したら、ラッパーを取り除くことができます。

一方、使用法のリファクタリングを無視して、モック化された構成クラスをテスト用のシングルトン ラッパーに単純に挿入することができます。これは、基本的に貧弱な依存関係の注入です。

于 2009-07-03T15:51:04.783 に答える