40

ここで以前にいくつかの質問に答えている間、そして私が最近行っているいくつかの作業から、なぜJavaが組み込みクラスのメソッドチェーンをサポートしていないのか疑問に思っています。

Carたとえば、クラスを作成する場合、次のようにvoidの代わりにreutrningすることで、クラスをチェーン可能にすることができます。this

public class Car {
    private String make;        

    public Car setMake(String make) {
        this.make = make;
        return this;
    }   
}

組み込みライブラリがこのように動作しない傾向がある特別な理由はありますか?メソッドチェーンの欠点はありますか?

メソッドチェーンの欠如を説明する何かを見落としているかもしれませんが、デフォルトでvoidを返すセッターメソッドはこれへの参照を返す必要があります(少なくとも私の目にはそうあるべきです)。これにより、次のような状況がはるかにクリーンになります。

container.add((new JLabel("label text")).setMaximumSize(new Dimension(100,200)));

注:必要に応じて、この方法でコーディングすることを妨げることはありません。

JLabel label = new JLabel("label text");
label.setMaximumSize(new Dimension(100,200));
container.add(label);

この決定の背後にある理由を聞いて非常に興味があります。これに関連するオーバーヘッドがあると推測する必要がある場合は、必要な場合にのみ使用する必要があります。

4

6 に答える 6

34

ええ 両方向で読みやすさの議論があります-一行に入れすぎようとするようなものがあります。

しかし、正直なところ、これは歴史的な理由によるものだと思います。たとえば、Swingが開発されていたとき、普及した「連鎖」動作は実際には普及しておらず、よく知られていませんでした。後で追加する必要があると主張することもできますが、そのようなものは、バイナリの非互換性や、Sun/Oracleが歴史的に非常に慎重にしてきたその他の問題を引き起こす傾向があります。

最近のJDKライブラリ(たとえばByteBuffer、主要なよく知られた例を参照)は、意味のある連鎖動作などを提供しています。

于 2012-07-19T13:26:24.310 に答える
19

私が考えることができるもう1つの理由は、パフォーマンス、より正確には、使用しないものにお金を払わないことです。return thisすべての方法の後で、それほどコストはかかりませんが、それでもいくつかの追加のCPUサイクルと1つのCPUレジストリが必要です。

return this戻り値を宣言するすべてのメソッドに暗黙的に追加するというアイデアさえありましたvoidが、それは拒否されました。

于 2012-07-19T13:28:16.660 に答える
9

本当の理由は推測できますが、厳密に言えば、それはあまりOOではないということも考えられます。

モデル化された世界のアクションを表すアクションとしてメソッドを表示する場合、メソッドチェーンは実際にはその図に適合しません。

もう1つの理由は、連鎖メソッドをオーバーライドしようとしたときに発生する可能性のある混乱である可能性があります。この状況を想像してみてください。

class Foo {
   Foo chainedMethod() {...}
}

class Bar extends Foo {
   Foo chainedMethod() {...} //had to return Foo for Java versions < 1.5
   void doStuff();
}

したがって、実行しようとするとnew Bar().chainedMethod().doStuff()、コンパイルされません。そして((Bar)new Bar().chainedMethod()).doStuff()、あまりよく見えません、それはしますか:)

于 2012-07-19T13:25:35.153 に答える
4

StringBuilderメソッドチェーンは通常、Builderパターンで使用され、これはクラスで確認できます。それ以外では、メソッドチェーンにより、コマンドと作成の分離が不明確になる可能性があります。たとえばrepaint()、流暢なインターフェイスの一部にする必要がありますか?それから私は持つことができました:

container.add(label).repaint().setMaximumSize(new Dimension(100,200)));

そして突然、呼び出しの順序が重要になり、メソッドチェーンに隠れてしまう可能性があります。

于 2012-07-19T13:28:28.190 に答える
1

メソッドチェーンを実装しない理由は、次のとおりです。

  • メソッドチェーンの最大の問題は仕上げの問題です。回避策はありますが、通常、これに遭遇した場合は、入れ子関数を使用することをお勧めします。コンテキスト変数を混乱させている場合は、ネストされた関数も適しています。

  • チェーン外のオブジェクトが実際に有効なnull以外のオブジェクトを返すという保証はありません。また、このスタイルのコードのデバッグは、多くの場合、非常に困難です。これは、多くの* IDE *が、デバッグ時にメソッド呼び出しを検査可能なオブジェクトとして評価しないためです。

  • チェーンメソッドの1つに引数を渡すために他のクラスにルーチンを呼び出す場合、主に行が非常に長くなるために渡すパラメーターが多い場合、混乱する可能性があります。

  • パフォーマンスの問題もあり、これはメモリで一生懸命働きます

于 2012-07-19T13:30:54.617 に答える
1

あなたは本当にデメテルの法則について尋ねています

「あなたの直接の友達とだけ話してください」

上記のリンクは素晴らしいリソースですが、そこで長い時間を費やしても、探していた答えが得られない可能性があることに注意してください。:-)

于 2012-07-19T13:48:25.553 に答える