5

私は、良い契約がどこで終わり、パラノイアが始まるのかを理解しようとしています. 本当に、私は良い開発者が何を気にかけ、何を省くべきなのかまったくわかりません:)

java.lang.Integer のような値を保持するクラスがあるとします。そのインスタンスは、他のオブジェクト (MappedObjects) (1 対多または多対多) によって集約され、MappedObjects のメソッド内でよく使用されます。パフォーマンス上の理由から、これらの関係を TreeMap (guava MultiMap は関係ありません) で追跡し、整数キーの範囲にバインドされた MappedObjects を高速に反復できるようにします。したがって、システムを一貫した状態に保つには、MappedObject.bind(Integer integer) メソッドを変更して、次のように Map を更新する必要があります。

class MappedObject {
    public void bind (Integer integer) {
        MegaMap.getInstance().remove(fInteger, this);
        fInteger = integer;
        MegaMap.getInstance().add(fInteger, this);
    }

    ...

    private Integer fInteger;
}

この最終メソッドを使用して抽象 MappedObject クラスを作成し、他のメソッドを強制的に継承させることもできますが、それは失礼です。メソッド bind() を使用して MappedObject をインターフェイスとして定義し、スケルトン実装を提供する場合、他の開発者は後でそれをオブジェクトに含め、Map を更新せずに自分でメソッドを実装するのを忘れる可能性があります。

4

5 に答える 5

4

はい、あなたは人々にあなたのコードで正しいことをするように強制するべきです。人々に間違ったことをさせる良い例は、サーブレット構成を自分で保存することを期待したサーブレットメソッドinit(ServletConfig config)ですが、明らかに、多くの人が構成を保存するのを忘れており、サーブレットを実行すると機能しませんでした。

APIを定義するときは、常にオープンクローズの原則に従う必要があります。クラスは拡張のためにオープンであり、変更のためにクローズされている必要があります。クラスがこのように機能する必要がある場合は、意味のある拡張ポイントのみを開く必要があります。他のすべての機能は、将来実装の問題につながる可能性があるため、変更に使用できないようにする必要があります。

于 2011-11-29T13:09:53.007 に答える
1

あなたのクラスはできるだけ簡単に使えるように設計されるべきだと思います。

開発者がメソッドをオーバーライドできるようにする場合は、契約を可能な限り文書化する必要があります。その場合、開発者はいくつかの基本的な機能をオーバーライドすることを選択するため、契約に準拠した実装を提供する責任があります。

開発者に機能の一部をオーバーライドさせたくない場合(セキュリティ上の理由から、賢明な代替手段がない場合など)は、その部分を最終的なものにするだけです。あなたの場合、bindメソッドは次のようになります。

class MappedObject {
public final void bind (Integer integer) {
    MegaMap.getInstance().remove(fInteger);
    internalBind( integer );
    MegaMap.getInstance().add(fInteger);
}

protected void internalBind( Integer integer ) {
 fInteger = integer;
}

...

private Integer fInteger;

}

internalBind()ここでは、開発者がメソッドをオーバーライドできるようにしますが、それbind()がマッピングを実行することを確認します。

要約すると、クラスの使用と拡張を(賢明に)可能な限り簡単にし、開発者が基本的な機能(たとえば、実際のバインディング)。

于 2011-11-29T13:10:00.463 に答える
1

最初に機能に集中し、不要なものはすべて残してください。ところで、反射を禁止することはできないので、誤用についてあまり心配する必要はありません。一方で、API は明確でわかりやすいものである必要があります。これにより、ユーザーは API を使用して何をすべきで、何をすべきでないかを明確に理解できるようになります。

于 2011-11-29T13:05:22.420 に答える
1

少なくとも、バグを防止するためのあらゆることを行う必要がありますが、労力はかかりません。

例:変数を null にできない場合は、intラッパー ( ) の代わりにプリミティブ型 ( ) を使用します。Integer

だからあなたのbind方法で。をバインドするつもりがない場合は、 as パラメータ タイプの代わりにnull使用します。intInteger

于 2011-11-29T13:06:06.347 に答える
0

APIユーザーが愚かだと思う場合は、誤った使用を禁止する必要があります。そうでなければ、あなたは彼らがしなければならないことをするために彼らの邪魔をするべきではありません。

クラスとメソッドの文書化と適切な命名は、APIの使用方法を示す必要があります。

于 2011-11-29T13:09:49.547 に答える