web-dev-qa-db-ja.com

ビルダーが独自のクラスファイルではなく内部クラスである必要があるのはなぜですか?

たくさんの Builder Patternの例では、Builderを、それが構築するオブジェクトの内部クラスにします。

これは、Builderが何を構築するかを示すため、ある程度の意味があります。ただし、静的に型付けされた言語では、Builderが何を構築するかがわかっています。

一方、Builderが内部クラスである場合、あなたはすべきであるBuilderの内部を見ることなくBuilderがどのクラスを構築するかを知っています。

また、ビルダーを内部クラスとして持つと、外部クラスから参照できるため、インポートの数が減ります。

そして、Builderが同じパッケージ内にあるが、StringBuilderのような内部クラスにはない実用的な例があります。 Buildershouldと名付けられているため、Stringを作成していることをご存知でしょう。

そうは言っても、Builderを内部クラスにするために私が考えることができる唯一の正当な理由は、クラスのBuilderが何であるかを知っているか、名前を知らなくても、命名規則に依存していないことです。たとえば、StringBuilderStringの内部クラスであった場合、おそらくそれが私が思ったよりも早く存在したことを推測しました(推測)。

Builderを内部クラスにする他の理由はありますか、それとも単に好みや儀式に帰するのですか?

24
Nathanial

これを行う理由は、内部クラス(ビルダー)が、構築しているクラスのプライベートメンバーにアクセスできるようにするためだと思います。

から http://docs.Oracle.com/javase/tutorial/Java/javaOO/nested.html

非静的なネストされたクラス(内部クラス)は、それらがプライベートとして宣言されている場合でも、囲んでいるクラスの他のメンバーにアクセスできます。

...

2つのトップレベルのクラスAとBについて考えてみましょう。Bは、そうでなければプライベートとして宣言されるAのメンバーにアクセスする必要があります。クラスA内でクラスBを非表示にすることで、Aのメンバーをプライベートに宣言し、Bがそれらにアクセスできるようになります。

...

インスタンスメソッドと変数の場合と同様に、内部クラスはそれを囲むクラスのインスタンスに関連付けられ、そのオブジェクトのメソッドとフィールドに直接アクセスできます。

これを説明するためのコードを次に示します。

class Example {

    private int x;

    public int getX() { return this.x; }

    public static class Builder {

        public Example Create() {
            Example instance = new Example();
            instance.x = 5; // Builder can access Example's private member variable
            return instance;
        }
    }
}

静的クラスとして、Builderには、関連付けられているExampleの特定のインスタンスはありません。ただし、例のインスタンス(またはそれ自体が作成するインスタンス)を指定すると、Builderは引き続きそのインスタンスのプライベートメンバーにアクセスできます。

30

この場合、「べき」はありません。別のクラス内でビルダーを定義したり、別のクラスに分離したりすることは、ビルダーパターンに直交します。多くの例では、1つの一貫したファイルでコードを提示するのが便利なため(プライベートメンバーにアクセスするためでもありますが、コンテキストにも依存します)。それ以外の場合はお気軽に

1
AZ01