20

CheckstyleルールDesignForExtensionがあります。それは言います:あなたがabstractでもfinalでも空でもないpublic/protectedメソッドを持っているなら、それは「拡張のために設計された」ものではありません。根拠については、Checkstyle ページのこのルールの説明をお読みください。

この場合を想像してみてください。いくつかのフィールドを定義する抽象クラスと、それらのフィールドの検証メソッドがあります。

public abstract class Plant {
    private String roots;
    private String trunk;

    // setters go here

    protected void validate() {
        if (roots == null) throw new IllegalArgumentException("No roots!");
        if (trunk == null) throw new IllegalArgumentException("No trunk!");
    }

    public abstract void grow();
}

Plant のサブクラスもあります。

public class Tree extends Plant {
    private List<String> leaves;

    // setters go here

    @Overrides
    protected void validate() {
        super.validate();
        if (leaves == null) throw new IllegalArgumentException("No leaves!");
    }

    public void grow() {
        validate();
        // grow process
    }
}

Checkstyle ルールに従って、 Plant.validate() メソッドは拡張用に設計されていません。しかし、この場合、どのように拡張を設計すればよいのでしょうか?

4

2 に答える 2

17

派生 (拡張) クラスが提供された機能を完全に置き換えてしまう可能性があるため、ルールは不平を言っています。これは、型がどのように拡張されるかを十分に考慮していないことを強く示しています。代わりに何をしてほしいかというと、次のようなものです。

public abstract class Plant {
    private String roots;
    private String trunk;

    // setters go here

    private void validate() {
        if (roots == null) throw new IllegalArgumentException("No roots!");
        if (trunk == null) throw new IllegalArgumentException("No trunk!");
        validateEx();
    }

    protected void validateEx() { }

    public abstract void grow();
}

誰かが独自の検証コードを提供することはできますが、事前に作成されたコードを置き換えることはできないことに注意してください。メソッドの使用方法によっては、validate代わりに public final にすることもできます。

于 2009-03-19T15:23:55.287 に答える