2017-10-11 8 views
-1

私はUtilクラスのためにJavaの静的メソッドのファンです。しかし、私はいくつかの同僚の間で、静的メソッドは決して外部リソースを使用すべきではないといういくつかの議論に出会った。しかし、なぜそれが悪い、あるいは危険なのかを説明することはできません。私が見つけた唯一の理由は、テスト中にその外部リソースを模擬するのは難しいかもしれないということです。しかし、それは本当に唯一の理由ですか?なぜ外部リソースに静的メソッドを使用しないのですか?

以下に、静的メソッドの例を示します。静的に使用するのが悪いアプローチであるべき理由を理解したいと思います。

public class JmsUtil { 
    public static String sendBytesMessage(byte[] messageBytes) throws JMSException, NamingException { 
     String jmsMessageID = null; 
     Connection connection = null; 
     try { 
      Context context = new InitialContext(); 
      ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("ourfactory"); 
      Queue queue = (Queue) context.lookup("ourqueue"); 

      connection = connectionFactory.createConnection(); 
      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 
      MessageProducer messageProducer = session.createProducer(queue); 
      BytesMessage bytesMessage = session.createBytesMessage(); 
      bytesMessage.writeBytes(messageBytes); 

      messageProducer.send(bytesMessage); 
      jmsMessageID = bytesMessage.getJMSMessageID();  
     } finally { 
      if (connection != null) { 
       connection.close(); 
      } 
     } 
     return jmsMessageID; 
    } 
} 

敬具

+1

静的メソッドに問題はありません。それはちょうどあなたが必要なものに依存します。多くの静的メソッドを持つ、実際にはStringUtils、apacheのような素晴らしいツールがあります。静的なものをモックしたい場合は、Powermockを使うことができます。とにかく、この質問は私には分からないようですが、これは意見に基づくものに似ているからです。 –

+6

'sendBytesMessage'はあなたのサンプルコードで' static'とマークされていません – tommyO

+4

静的メソッドは、テストで外部リソースを模擬するために難しくなります(またはPowerMockitoのようなものを使用したくない場合は不可能)。おそらく読んで[静的メソッドは、テスト可能性への死です](http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/)。 –

答えて

0

は、2つのクラス

class Foo extends Blob{ 

public void someMethod(){ 
byte[] message = createMessage(); 
JmsUtil.sendBytesMessage(message); 
} 

} 

class Bar extends Blob{ 
Sender sender; 

public void someMethod(){ 
byte[] message = createMessage(); 
sender.sendBytesMessage(message); 
} 

} 

クラスFooを検討し、クラスバーがSenderインタフェースを実装するクラスを使用しているが、ユーティリティクラスを使用しています。

まず、あなたの質問で言及しているように、送信者を模擬してテストするのはずっと簡単です。それ以外の場合は、プロセス全体を検証するメッセージを受信できるインフラストラクチャを作成する必要があります。

2つ目は、抽象的な機能の可能性を失っていることです。どのようにメッセージを送信するかを変更する必要がある状況を想像してください。最初のケースでは、システムのロジックを扱うクラスを変更する必要があります。メッセージを送信するプロセスを抽象化していくにつれて、アプリケーションのブートストラップを担当するモジュールで変更を行う必要があります。場合によっては、設定ファイルで変更が行われ、ライブシステムで行われる場合があります。

0

主な問題は、実装を簡単に変更できないことです。静的メソッドはインターフェースを持つことができません。

これはさまざまな理由で悪いことですが、外部リソースへのアクセスに焦点を当てましょう。

静的メソッドでは、テスト容易性は大きな問題になります。テストのために外部リソースが必要であるか、静的メソッドの "周り"をテストするかのどちらかです。代わりにMessageSenderインターフェイスがあれば、簡単にテストで模擬し、期待通りに呼び出されたかどうかだけを確認することができます。

外部リソースへのアクセスを飾る必要がある場合があります。たとえば、ある検索ルックアップクライアントがある場合は、後でパフォーマンスを向上させるためにキャッシュを追加することができます。これは、インターフェイスではるかに簡単です。

関連する問題