2016-09-20 8 views
1

私はより高いレベル(等、コピー等、ムーブ)非静的メソッド

をデータ移動タスクを実行するJavaでアプリケーションを作成しています、私は、オブジェクトに対してこれらの操作を提供することができますレベル。

サンプルコード:

public class DataSource { 

    public boolean copy(DataSource dsDestination); 

    public boolean copy(DataSource dsDestination, Filter filter); 

    public boolean move(DataSource dsDestination); 

    public boolean exists(); 

    // some other 10-15 methods 

} 

または私は静的メソッドでユーティリティを提供することができます:1は、メモリ管理の面でより良いアプローチです

public class DataSourceUtil { 


    public static boolean copy(DataSource dsSource, DataSource dsDestination); 

    public static boolean copy(DataSource dsSource, DataSource dsDestination, Filter filter); 

    public static boolean move(DataSource dsSource, DataSource dsDestination); 

    public static boolean exists(DataSource dsSource); 

    // some other 10-15 methods 

} 

+7

現在はメモリ管理を無視します。関連性は低いです。文脈のなかで最も合理的なのはどれですか?どちらが最も読みやすいコードに終わるのでしょうか? ( 'DataSource'に入れることができ、すべての操作で* DataSourceが必要な場合はインスタンスメソッドにしてください...) –

答えて

2

ゴールデンルールは:スタティック異常良いOOデザイン内です。あなたはそれを行うのが正当な理由がある場合にのみ使用します。

あなたが見ると、のstaticは、クラス間の直接結合につながります。そしてそれはテストをより困難にします。もちろん、静的メソッド自体は簡単にテストできますが、静的メソッドを呼び出すメソッドをテストする場合(静的メソッドの処理に影響を与える必要がある場合)はどうなりますか?その後、これらの静的な呼び出しを模擬するためにPowermockに向かう誘惑になるかもしれません。それは本当に素晴らしい考えではありません。

あなたは次のように、機能性、あなたより良い用途のインタフェースを分離することを主張した場合:

public class DataSource { 
... ctor, equals, ... methods 
} 

public interface DataSourceCopyAbility { 
    public void copy(DataSource source, DataSource destintion); 

プラス対応する独自の実装クラス。

編集:もちろん、便宜は静的メソッドを使用する正当な理由です。たとえば、私はコード内で常にObjects.requireNonNull()を使用しています。 しかし、:これらは標準のAPI呼び出しです。私のコードでそれらを使用しているとき、私は実際にそれらが動くように気にしません。私はこの種の静的メソッド呼び出しを "模倣"したくなることは決してありません!

最後に、操作が成功したときにに戻したいとします。悪い考え:ブール値は真と偽を区別するためにだけ使用されるべきです。彼らはではなく、リターンコードです!

DataSourceをコピーするような複雑な操作が失敗した場合 - を例外とします!また、例外なく実行したい場合は、独自のReturnCodeクラスを定義して、失敗した操作についての洞察を得ることができます。 Apache Commons Langライブラリとjava.lang.Objectsの経験から描画

+0

本当ではないIMOでは、静的メソッドNPEから保護します。 [Objects](https://docs.oracle.com/javase/7/docs/api/java/util/Objects)を参照してください。html) –

+0

私は知っています。私は常にrequireNonNull()を使用しています。しかし、その方法の「範囲」はA)非常に小さいB)非常に正確C)私の生産コードで心配するものではない。言い換えれば、私のプロダクションコードが**この種の静的メソッドを使用しているとき、それらのメソッドを改ざんする必要はありません。彼らはそこにいて、それぞれのテスト内でそれらを呼び出すことに問題はありません。 "データソース"の "移動"を比較する。しかし、私はそれに言及するために私の答えを更新します。 – GhostCat

0

これらのメソッドで記述している機能によって異なります。機能がオブジェクト固有のフィールド値を使用していない場合、静的メソッドを使用すると正しいオプションになります。

すなわち、すべての操作がDatasource isselfあるソースオブジェクトを必要として、私は、その後、@ジョンスキートに同意し、使用している変数情報をオブジェクトに固有ではなく、データはクラスレベル

1

に共通していることを確認してくださいそれらはインスタンスメソッドでなければなりません。それらはObjectクラスのequalsに似ています。

テスト可能な視点から、インスタンスメソッドは簡単にテストできます。

0

メモリ管理の視点は、勿論、同等です。これらの関数は、コンパイルされたコードを共有しており、このコードは読み取り専用メモリ領域に格納されます。これらの2つの間の違いだけがポインタコンテキストです。したがって、静的または非静的を選択した場合、それ以上のスペースを占めるべきではありません。コンパイルされた言語のほとんどは同じ方法である。

0

は、静的メソッドの利点が、彼らはJavaコードでこのような何かを見るために非常に一般的ですNullPointerException

からの保護を提供することができるということです。

if (x != null && a.equals(otherX)) ... 

またはリテラルを左側に置く練習:

if ("literal".equals(str)) ... 

これらはすべてNPE保護の方法です。これは、上記のliberaryの理由の一つであり、静的メソッドの場合です:

if (ds.copy(dest) == true) ... // may throw NPE 

if (DataSourceUtil.copy(ds, dest) == true) ... // NPE protection 
0

違い:

dataSource.copy(); 

コピーは私の責任ではない、それは、DataSourceの責任です。

コピーは私の責任ですが、複製は避けるため、ソースコードはユーティリティクラスで作成されています。

2

メモリ管理については忘れてください。

どちらの方法を使用しても、copyまたはmoveを呼び出すために、2つのDataSourceオブジェクトを作成します。メモリ使用量にはほとんど違いがありません。

代わりに注目すべきは、読みやすさと美しさです。:)

は、これら二つの比較:

someData.copy(otherData); 
DataSourceUtils.copy(someData, otherData); 

秒1は、より冗長です。また、データをコピーするのに役立ついくつかの他のもの(DataSourceUtils)が必要なようです。私たちがデータを自分自身(最初のもの)にコピーさせるのであれば、書く方が少なくて済みます。あなたは第二の方法でこれを行うことはできません

someData.copyTo(otherData); 

:私が指摘したい

もう一つのポイントは、あなたがそれをたくさん読みやすくするために最初のものでToを追加できるということです。

関連する問題