1

コード例は C# ですが、これは一般的な OO の質問です。

オブジェクト指向のルールに従って、クラスの結合を最小限に抑え、可能な限りメンバーを非公開にする必要があることなどを知っています。

次の例を検討してください。

プログラムの文字通りすべての面で使用されるある種のデータセット(System.Data.DataSetについては話していません)を持つ難解なプログラムを作成しています。実際、このプログラムは基本的に、データ セットをロード、表示、操作、および保存するためだけに存在します。さらに、一度にロードできるデータセットは 1 つだけであり、プログラムが開いたときにロードされます。

オブジェクト指向のルールに厳密に従えば、

public void ShowSomeGraphs(IData data)
{
  // do stuff with data which implements IData
}

ただし、たとえば にpublic static Dataメンバーを格納する可能性があります。Program

public void ShowSomeGraphs()
{
  // do stuff with Program.Data
}

一方で、大幅に増加したクラス結合のために、わずかに短い関数シグネチャを交換しました。一方、実質的にすべての関数にDataパラメーターを渡すことはなくなりました。

正しい答えはおそらく次のとおりです。可能な限りクラスの結合を避けます。ローカル データ変数は単なるポインターであるため、メモリ オーバーヘッドは無視できます。また、クラスが分離されているため、後で別の場所で使用できます。

現実的に言えば、Data クラスの構造は別のアプリケーションでは驚くほど異なる可能性が高いため、このプログラムからクラスを取り出して、微調整なしで別の場所にドロップできるわけではありません。ドロップインできるような方法でクラスを作成するために必要な余分な時間と労力は、利害関係者に正当化するのが難しい場合があります。

私は現在、この種のプログラムに取り組んでおり、OO-canon アプローチを使用しました。データ パラメーターは必要な場所に渡されます。将来のコードの再利用のためにデータ セットを一般化するために、IData インターフェイスとのクラス結合を最小限に抑えました。アプリケーションを考えると、このコードが再利用されることはないとほぼ確信しています。これらの追加のインターフェイスと抽象化がなければ、プログラムはエンド ユーザーに関する限りまったく同じように機能していたでしょうが、私にとっては頭痛の種と開発時間が大幅に削減されていたでしょう。

これについてあなたはどう思いますか?クラスが後で別の場所で使用されているのを確認できない場合は特に、できる限りクラスが分離されるように、インターフェイスと一般化を作成するために余分な時間を費やすことは正当だと思いますか?

4

3 に答える 3

1

苦しんではいけません。真剣に。

ソフトウェアのパラダイム/パターンは私たちを助けるためのものであり、独断的に従わないためのものです。

あなたはあなたの質問であなたが緩い結合のやり過ぎを考慮していることを明らかにします、そしてあなたはその理由を正当化することができます。したがって、使用しないでください。

于 2011-11-09T09:30:21.197 に答える
1

シングルトン パターンを使用して、IData インターフェイスを取得するためのメソッドまたは読み取り専用プロパティを提供するのはどうですか? この方法では、非常に薄いシングルトン クラスに結合されるだけで、データ セットとのやり取りはすべて IData インターフェイスを介して行われます。

(密結合は絶対に避けたいと思います。このアプリで多くのことを行う予定がない場合でも、開発中に問題が発生する可能性があります。インターフェース。)

上記で提案されたシングルトン ソリューションのコード サンプル:

using System;

public class MyClass {
    public static void Main() {
        // simple usage:
        Console.WriteLine("From Main: " + Singleton.Instance.IMyData.GetData());
        // client code from another type:
        new ClientObj().DoWork();
        Console.ReadKey();
    }
}

public sealed class Singleton {
    // standard singleton stuff:
    private static readonly Singleton _instance = new Singleton();
    private Singleton(){}
    public static Singleton Instance {get { return _instance; }}
    // data interface stuff:
    private MyData _myData = new MyData();
    public IData IMyData {get { return _myData; }}
}

// the interface:
public interface IData {
    string GetData();
}

// concrete implementation of the data class
public class MyData : IData {
    public string GetData() {return "Hello World!";}
}

// example of a type using the singleton and the IData interface
public class ClientObj {
    public void DoWork() {
        IData data = Singleton.Instance.IMyData;
        string str = data.GetData();
        Console.WriteLine("From other obj: " + str);
    }
}

いくつかの注意事項:上記のコード サンプルは、シングルトンと共有インターフェイスの概念を示すために完全に削除されています。スレッド セーフは実装されておらず、データ オブジェクトの初期化などもありません。

于 2011-11-08T23:25:17.347 に答える
0

さて、あなたのテキストには 1 つの大きな前提があります。プログラムには常に 1 つのデータ セットしかないということです。その状態がずっと続くと確信していますか?ワード プロセッサが一度に 1 つのテキストしか保持できない時代がありました。今日では、一度に複数のファイルを開くことができるのが標準です。最初の Web ブラウザーが一度に 1 つの Web ページしか開けなかったとしても、私は驚かないでしょう。今日では、同時に複数のページを開くことができない Web ブラウザを使用する人は誰もいません。プログラム内に確実に 1 つしか存在しないと言えるようなオブジェクトは、非常にまれだと思います。実際、私がグローバル オブジェクトまたはシングルトンにする唯一のものは、オブジェクト ファクトリです。

一方、関数呼び出しごとにオブジェクトを渡すことは、私にはやり過ぎのようにも思えます。したがって、私は中間の立場に行きます。オブジェクトにその「グローバル」オブジェクトを記憶させて、コンストラクターを介して渡すだけでよいようにします。これにより、各オブジェクトは 1 つの Data オブジェクトに制限されますが、必要に応じてプログラムに複数の Data オブジェクトを簡単に含めることができます。

于 2011-11-08T23:39:35.480 に答える