私は今、このようなコードで作業しています
public String getName(User user) {
user.setSth(...);
return user.getName();
}
パラメータとして渡されたオブジェクトを変更するのは悪い習慣だと思います。そのようなコードを検出するツールはありますか?findbugs、pmd、checkstyleを調べましたが、これに対するチェックは見つかりませんでした。
PS悪い例でごめんなさい。
私は今、このようなコードで作業しています
public String getName(User user) {
user.setSth(...);
return user.getName();
}
パラメータとして渡されたオブジェクトを変更するのは悪い習慣だと思います。そのようなコードを検出するツールはありますか?findbugs、pmd、checkstyleを調べましたが、これに対するチェックは見つかりませんでした。
PS悪い例でごめんなさい。
あなたはすでに正しい方向に進んでいると思います。この種のコードを検出するための最良のツールは、ほぼ間違いなくFindbugsです。ただし、おそらく、このパターン用に独自の検出器を作成する必要があります。 ディテクタを作成する方法の例を次に示しますが、それは正確に探しているディテクタではありません。
警告: 副作用のあるゲッターが常に悪いスタイルであることに、私は本当に同意しません。しかし、本当にそういうものを見つけたいのであれば、Findbugs をお勧めします。
ツールの観点からは、「getName」と「setSth」は単なるメソッド呼び出しであるため、何も見つかりません。人間は「これはゲッターだ」「これはセッターだ」と言いますが、ツールはそうではありません。実際、ゲッターは引数を受け入れないため、getName() はゲッターではありません。
メソッドは常にオブジェクトを変更するため、ツールは異常を検出できません。
このルールを適用したい場合は、findbugs と PMD の拡張を検討してください。どちらも、追加の制約を定義できます。あなたが探しているのはおそらく次のとおりです。
次に、警告を出力します。それほど時間はかかりません。これを実行すると、「偽陽性」の数が表示されます (実際には問題のないメソッドに関する警告)。これは、これをさらに追求する価値があるかどうかを判断するのに役立ちます。さらに、履歴書に追加する新しいアイテムがあります:)
User
不変にすることができます(それfinal
を宣言し、すべてのプロパティfinal
を宣言し、セッターをリモートにします。どこでも実行できるわけではありませんが、多くの場所ではそれが適切であり、それを他の関数に渡すのに問題はありません)。
何かを「変更」する必要がある場合はnewId
、そのサンプルのような関数を実装できます。
public final class User {
private final String name;
private final int id;
User(String name, int id) {
this.name = name;
this.id = id;
}
public User newId(int newId) {
return new User(this.name, newId);
}
//getters here;
}
組み込みのString
, Integer
, ... クラスもそれを行います。
「ゲッター」のみを含む UserView というインターフェースを作成し、それを User に実装させ、新しい UserView インターフェースをパラメーターのタイプとして使用することができます。
interface UserView{
public String getName();
...
class User implements UserView...
public String getName(UserView user) {
user.setSth(...); // Will not compile
return user.getName();
}
const
実際、これは C++ では修飾子を介して非常に簡単に実行できたものです。パラメータをとして定義し、そのパラメータに対しては、通常はゲッターconst
として定義されたメソッドのみを呼び出すことができます。const
Java にはこれがなく、率直に言って、私はあまり気にしません。前述のように、この動作をチェックできるソース コード アナライザーと、同様にこれを行うメタプログラミング メソッドがあります。
個人的には、メソッドに適切な名前が付けられていれば、オブジェクトを渡しても問題はなく、変更されていると思います。
コンパイラが通常行うよりも高いレベルでコードについて「推論」できるツールがあります。たとえば、宣言型メタプログラミングは、プログラムを作成して、別のプログラムが特定の設計に準拠しているかどうかをチェックしたり、逆にコードの匂いやアンチパターンを調べたりできるようにする分野です。
いくつかのリンク:
http://www.cs.bris.ac.uk/Publications/pub_master.jsp?id=1000273
そして残りのために
渡された参照と同じようにパラメーター値を不変にすることを強制する C++ の "const" のようなものを探しています。
このような副作用はユーザーを驚かせる可能性があるため、これは「悪い」と主張しています。それは有効ですが、望ましくない驚きである場合にのみ有害です.