10

Robert C. Martin によるクリーンなコードによると、メソッドには小さな署名が必要です。最良のケースは、パラメーターをまったく持たないメソッドです。代わりに、状態変数を使用することをお勧めします。これは本当に便利です。しかし、ステートレス セッション Bean はどうでしょうか。

SLSB は状態を持つことができるため、名前はちょっとわかりにくいです。以前の EJB 呼び出しからの状態を使用しないように、ハウスキーピングを行うだけで済みます。

きれいなコードに戻る: SLSB でもインスタンス変数を使用したいと思っています。これは問題なく動作し、十分に注意すれば、パブリック メソッドの呼び出しごとに状態が上書きされるため、状態の不一致に問題はありません。

ここまでは順調ですね。しかし、使用済みの Bean がプールに戻ったらどうなるでしょうか。それはそれと共にその状態を取ります。状態のサイズによっては、これが実際のメモリ リークになる可能性があります。JBoss は Bean に非常に寛大であり、非常に大量の Bean を生成して深刻なメモリ消費を引き起こします。

したがって、1 つの方法は、Bean メソッドが存在し、Bean がプールに返される前に状態をクリーンアップすることです。しかし、これは避けるべき無駄なコードのように思えます。

この問題に対処する適切な方法はありますか? この状況でのベストプラクティスは何ですか?

4

4 に答える 4

1

プロキシを使用せずにメソッド間で呼び出しを行うため、インスタンス変数を SLSB に保持することは完全に可能です。例えば:

@Stateless 
public class MyEJB {
    private String myVar;

    public void receiveVar(String myVar) {
        this.myVar = myVar;
        useVar();
    }

    private void useVar() {
        // do something with var
    }
}

ポイントは、この SLSB を別の SLSB に注入すると、すべてのメソッド呼び出しがプロキシを通過して実際の EJB を実現することです。そのため、メソッドがプロキシ インスタンスで呼び出されたときに実際のインスタンスがプールから取得されることを考慮すると、プロキシが 2 回以上の呼び出し間でプールされた同じインスタンスを使用するという保証はありません。そのため、宣言されたクラス属性の値を保証することはできません。

SLSB がプールに戻ると、設定されたすべての値が取り込まれます (ベンダーによって変わる可能性があると思いますが、よくわかりません)。ただし、プールされた SLSB インスタンスがすでに構成済みの属性値を持っている可能性は十分にあります (許容されます)。

私はここであなたのポイントを理解していませんでした:

ここまでは順調ですね。しかし、使用済みの Bean がプールに戻ったらどうなるでしょうか。それはそれと共にその状態を取ります。状態のサイズによっては、これが実際のメモリ リークになる可能性があります。JBoss は Bean に非常に寛大であり、非常に大量の Bean を生成して深刻なメモリ消費を引き起こします。

SLSB で使用できる「大きな状態」の例はありますか?

そして最後に:

値を処理する最善の方法は、使用する状態変数を常に処理することだと思います。使用前のセッティングと使用後のクリーニング。そして、ベスト プラクティスは、この種の混乱を招く状況を避けることです。

それが役に立てば幸い。

于 2016-06-21T12:31:51.783 に答える
0

Robert C. Martin によるクリーンなコードによると、メソッドには小さな署名が必要です。

通常、引数として渡す (オブジェクトを転送する) ことを好みます。このようにして、メソッドのシグネチャに影響を与えることなく、渡す内容を変更できます。

また、実際の基本クラスではなく、インターフェイスを渡すことをお勧めします。

public void doSomething(IMyTransferObject arg){
 ...
}

IMyTransferObjectインターフェイスはどこですか

interface IMyTransferObject {
   ...
}

class TransferObject implements IMyTransferObject{
  private String name;
  private String game;
  ... accessor / mutator
}

最良のケースは、パラメーターをまったく持たないメソッドです。代わりに、状態変数を使用することをお勧めします。これは本当に便利です。しかし、ステートレス セッション Bean はどうでしょうか。

これは宗教的に従うことができず、そうする理由はありません。

于 2012-04-24T14:38:20.073 に答える
0

人生をシンプルに保ち、パラメータを渡すだけです。他の方法で行うことができたとしても、ステートレス EJB の意図から、そうすべきではないことは明らかです。

ゼロパラメータの目標を目指すFWIWは、私にはばかげているようです。はい、少数を目指しますが、それ自体のためにゼロを目指すのは馬鹿げています。

于 2012-04-24T14:07:30.813 に答える
0

http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.htmlから:

ステートレス セッション Bean

ステートレス セッション Bean は、クライアントとの会話状態を維持しません。クライアントがステートレス Bean のメソッドを呼び出すと、Bean のインスタンス変数には、そのクライアントに固有の状態が含まれる場合がありますが、呼び出しの間だけです。メソッドが終了すると、クライアント固有の状態は保持されません。ただし、クライアントは、プールされたステートレス Bean のインスタンス変数の状態を変更することができ、この状態は、プールされたステートレス Bean の次の呼び出しまで保持されます。メソッドの呼び出し中を除いて、ステートレス Bean のすべてのインスタンスは同等であるため、EJB コンテナはインスタンスを任意のクライアントに割り当てることができます。つまり、ステートレス セッション Bean の状態は、すべてのクライアントに適用される必要があります。

私は EE の専門家ではありませんが、フィールドを計画通りに使用することは技術的に許可されているように思えます。

新しいメソッドが呼び出されるたびに、インスタンス フィールドが新しいデータで更新されていることを確認する必要があると思います。また、ブロックないようにするために、メソッドが終了した後に参照を削除していることを確認する必要があると思います。まだいくつかのプールに保持されている「古い」Beanで参照されているという理由だけで、古いオブジェクトのガベージコレクション。

私はそのようなパターンを提案します:

public class MyBean{

  private SomeClass firstObject;
  private SomeOtherClass anotherObject;
  private AndAnotherClass thirdObject;

  public void theMethod(firstObject, anotherObject, thirdObject){
    try {
      this.firstObject = firstObject;
      this.anotherObject = anotherObject;
      this.third = thirdObject;

      startProcessing();

    }finally {
      this.firstObject = null;
      this.anotherObject = null;
      this.third = null;
    }
  }

  private void startProcessing() {
    doStep1();
    doStep2();
    doStep3();
  }

  [...]
}

まだ多くのコードがありますが、一貫してそのスタイルに固執する場合は、「theMethod」の部分を自動的にスキップして、「startProcessing」の部分を読み続けます。ここで、すべてがきれいに、パラメーターなしで得られます。

于 2013-12-10T16:57:34.790 に答える