20

クラス'Application'があるとします。初期化するには、コンストラクターで特定の設定が必要です。また、設定の数が多すぎて、独自のクラスに配置する必要があると仮定しましょう。

このシナリオの次の2つの実装を比較してください。

実装1:

class Application 
{
   Application(ApplicationSettings settings) 
   {
       //Do initialisation here
   }
}

class ApplicationSettings 
{
   //Settings related methods and properties here
}

実装2:

class Application 
{
   Application(Application.Settings settings) 
   {
       //Do initialisation here
   }

   class Settings 
   {
      //Settings related methods and properties here
   }
}

私にとっては、2番目のアプローチが非常に望ましいです。2つのクラス間の関係を強く強調しているため、読みやすくなっています。どこでもApplicationクラスをインスタンス化するコードを書くと、2番目のアプローチはよりきれいに見えます。

ここで、Settingsクラス自体に同様の「関連」クラスがあり、そのクラスにも同様のクラスがあると想像してみてください。そのようなレベルを3つだけ実行すると、「ネストされていない」場合にクラスの命名が手に負えなくなります。ただし、ネストした場合でも、物事はエレガントなままです。

上記にもかかわらず、StackOverflowで、ネストされたクラスは外部に表示されない場合にのみ正当化されると言っている人を読んだことがあります。つまり、それらが含まれているクラスの内部実装にのみ使用される場合です。よく言われる反対意見は、クラスのソースファイルを含むサイズを肥大化させることですが、部分的なクラスはその問題の完璧な解決策です。

私の質問は、ネストされたクラスの「公開された」使用になぜ警戒するのかということです。そのような使用に反対する他の議論はありますか?

4

6 に答える 6

27

大丈夫だと思います。これは基本的にビルダー パターンであり、ネストされたクラスを使用すると非常にうまく機能します。また、ビルダーは外部クラスのプライベート メンバーにアクセスできるため、非常に便利です。たとえば、ビルダーのインスタンスを取る外部クラスでプライベート コンストラクターを呼び出すビルダーに Build メソッドを含めることができます。

public class Outer
{
    private Outer(Builder builder)
    {
        // Copy stuff
    }

    public class Builder
    {
        public Outer Build()
        {
            return new Outer(this);
        }
    }
}

これにより、外部クラスのインスタンスを構築する唯一の方法はビルダーを介することになります。

私はプロトコル バッファの C# ポートでこのようなパターンを使用しています。

于 2008-12-03T13:47:31.207 に答える
6

名前空間を使用して、関連するものを関連付けることができます。

例えば:

namespace Diner
{
    public class Sandwich
    {
        public Sandwich(Filling filling) { }
    }

    public class Filling { }
}

名前空間であるかのようにクラスを使用することよりも優れている点はusing、呼び出し側で必要に応じて省略形を使用できることです。

using Diner;

...

var sandwich = new Sandwich(new Filling());

Sandwichクラスを の名前空間であるかのように使用する場合Fillingは、完全な名前Sandwich.Fillingを使用して を参照する必要がありFillingます。

そして、それを知ってどうやって夜寝ますか?

于 2008-12-03T14:01:07.857 に答える
1

このトピックに関してMicrosoftが何を言っているかを確認することをお勧めします。基本的にそれは私が言うスタイルの問題です。

于 2008-12-03T13:44:09.530 に答える
0

私は主に、ネストされたクラスやコンテナクラスへのアクセスを微調整するためにネストされたクラスを使用します。

覚えておくべきことの1つは、ネストされたクラス定義は基本的にクラスメンバーであり、コンテナのすべてのプライベート変数にアクセスできるということです。

これを使用して、特定のクラスの使用を制御することもできます。

例:

public abstract class Outer
{
  protected class Inner
  {
  }
}

この場合、(クラスの)ユーザーは、Outerを実装している場合にのみ、Innerクラスにアクセスできます。

于 2008-12-03T13:44:42.023 に答える