2014-01-17 1 views
32

私はJavaでメソッド連鎖を実現したいと思います。Javaでメソッドチェーンを実現する方法は?

どうすれば実現できますか?

また、いつ使用するか教えてください。

new Dialog().setTitle("Title1").setMessage("sample message").setPositiveButton(); 

など

new Dialog().setTitle("Title1").setMessage("sample message"); 

など

new Dialog().setTitle("Title1").setPositiveButton(); 
+3

のようにそれを使うのか? –

+2

これは、通常、「流暢」または「流暢」プログラミングと呼ばれます。 – Pureferret

+0

流暢なAPIのためにセッターを使うのではなく、ダイアログのためのBuilderを作成します。そうすれば、フレームワークがvoidを返すようにセッターを制限するので、多くのbeanのようなアクセスはもはや機能しません。そのボイラープレートをすべて書きたいと思わない場合は、プロジェクトロンボクを見てください。 –

答えて

65

をあなたの方法はthisを返しておいてください。

public class Dialog { 

    public Dialog() { 

    } 

    public void setTitle(String title) { 

     //Logic to set title in dialog 
    } 

    public void setMessage(String message) { 

     //Logic to set message 
    }  

    public void setPositiveButton() { 

     //Logic to send button 
    } 
} 

は、私は次のように、私が使用できるメソッドチェーンを作成したいです好きな:

public Dialog setMessage(String message) 
{ 
    //logic to set message 
    return this; 
} 

この方法では、いずれかのメソッドを呼び出すたびに同じオブジェクトが返され、別のメソッドを呼び出すことができます。

このテクニックは、オブジェクトの一連のメソッドを呼び出すときに便利です。これを実現するために必要なコード量を減らし、一連のメソッドの後に単一の戻り値を持たせることができます。

ダイアログがあろう表示するために必要なコードの量を削減する例:

// Your Dialog has a method show() 
// You could show a dialog like this: 
new Dialog().setMessage("some message").setTitle("some title")).show(); 

単一の戻り値を使用する例は次のようになります

// In another class, you have a method showDialog(Dialog) 
// Thus you can do: 
showDialog(new Dialog().setMessage("some message").setTitle("some title")); 

使用例デニスがあなたの質問にコメントしたビルダーパターン:

new DialogBuilder().setMessage("some message").setTitle("some title").build().show(); 

ビルダーパットternは、オブジェクトが構築される前にクラスの新しいインスタンスのすべてのパラメータを設定することができます(構築後に値を設定するのは、構築時に値を設定するよりもコストがかかります)。上記の例では

setMessage(String)setTitle(String)DialogBuilderクラスに属し、それらが呼びかけているDialogBuilderの同じインスタンスを返します。 build()メソッドはDialogBuilderクラスに属しますが、Dialogメソッドを返します。show()メソッドはDialogクラスに属します。

エクストラ

これは、あなたの質問に関連していない可能性がありますが、それはあなたとこの問題に遭遇して他人を助けるかもしれません。

これは、ほとんどのユースケースに適しています:継承を伴わないすべてのユースケースと派生クラスは、あなたがしているあなたが一緒にチェーンにする新しいメソッドを追加していないとき、継承を含むいくつかの特定の例導かれたオブジェクトとしてのメソッドの連鎖の結果を(キャスティングなしで)使用することには興味がありません。

基本クラスにメソッドを持たない派生クラスのオブジェクトのメソッド連鎖を使用する場合や、メソッドの連鎖で派生クラスの参照としてオブジェクトを返す場合は、a this questionの回答を見てください。ダイアログを表示するために必要なコードの量を削減する

+0

私はあなたの質問の一部を見逃したので、最後の使用例を追加しました。これらはメソッドチェインやBuilderパターンの唯一の用途ではないことに注意してください。ほとんどのコーディングパターン、アルゴリズム、テクニックと同様に、少しの創造性で古いパターン(アルゴリズム、テクニック)を新たに使用することができます:) –

+0

設定の振る舞いを変更するのは良い習慣ではありません。なぜなら、一部のフレームワークはsetterメソッドからの戻りを期待していないからです。 たとえば、モデルの設定者がいくつかの値を返す場合は、Cassandra Javaドライバでエラーが発生します。 – Vagif

0

例は次のようになります。

package com.rsa.arraytesting; 

public class ExampleJavaArray { 

String age; 
String name; 

public ExampleJavaArray getAge() { 
    this.age = "25"; 
    return this; 
} 

public ExampleJavaArray setName(String name) { 
    this.name = name; 
    return this; 
} 
public void displayValue() { 
    System.out.println("Name:" + name + "\n\n" + "Age:" + age); 
} 
} 

別のクラス

package com.rsa.arraytesting; 

public class MethodChaining { 

public static void main(String[] args) { 

    ExampleJavaArray mExampleJavaArray = new ExampleJavaArray(); 

    mExampleJavaArray.setName("chandru").getAge().displayValue(); 

} 

} 
+0

パッケージcom.rsa.arraytesting; パブリッククラスMethodChaining { \tパブリック静的無効メイン(文字列[] args){ \t \t ExampleJavaArray mExampleJavaArray =新しいExampleJavaArray()。 \t \t mExampleJavaArray.setName( "chandru")。getAge()。displayValue(); \t} } –

1

ただ、静的ビルダーメソッドを追加し、セッターメソッドの別のセットを作成します。例

class Model { 
    private Object FieldA; 

    private Object FieldB; 

    public static Model create() { 
     return new Model(); 
    } 

    public Model withFieldA(Object value) { 
     setFieldA(value); 
     return this; 
    } 

    public Model withFieldB(Object value) { 
     setFieldB(value); 
     return this; 
    } 
} 

については ...

そして、Builderパターンと同様

Model m = Model.create().withFieldA("AAAA").withFieldB(1234);