情報秘匿は、モジュール間の依存関係を解消して、個別に開発、テスト、最適化を目指しています。
情報秘匿とカプセル化がなされたモジュールは、並列的に開発することができますので、システム開発の速度が早くなり、他のモジュールに影響を与える心配なく、デバッグが可能できるようになります。
この他にも、メンテナンスの容易さ、ソフトウェアの再利用の容易さなど様々なメリットを享受するために、情報秘匿を考慮した方がいいです。
情報秘匿の重要な原則の一つは、各クラスのメンバーは、可能な限り接近できないようにすることです。
Javaのは、4つのアクセス権限を提供しています。
private クラスの内部から接近が可能です。
package-private 同じパッケージの中で接近可能です。
protected 宣言されたクラス及びサブクラスから接近可能です。
public 全て公開します。
コードの使い道に合わせて可能な限りの情報を隠してください。
コードとは関係なく、APIなどで配布するとき、一度publicに公開すると
その後は、publicに変えることが簡単にできません。
そのAPIの利用者がpublicを参照している可能性が大きいためです。
オブジェクトフィールド(instance field)は絶対にpublicで宣言しないでください。
オブジェクトフィールドをpublicとして宣言すると
その値が変更可能になって、フィールドに格納する値を制限することができなくなります。
当然、そのフィールドを使ったマルチスレッドも安全ではなくなります。
スレッドが処理の途中、プログラマが作成した参照オブジェクト内のフィールドの値が引き続き変わったらデータの一貫性が保たなくなります。
しかし、例外もあります。
皆さん、public static finalフィールドをご覧になったことがあると思います。
このようなフィールドは、時々、文字列としても使用することもあります。
このフィールドは、必ず基本型の値を格納したり、
変更が不可能なオブジェクトを参照する必要があります。
また、長さが0ではない配列は、常に変更が可能なので、public static final配列フィールドを置くか、配列フィールドを返すアクセサ定義してはいけません。
public static final Thing[] VALUES = { . . . }
// このような使い方はいけません。
上記のコードは、以下のようにlistを使って他のオブジェクトにして返したり、
配列がcloneableを実装していることを利用し、「clone()」メソッドを使用することもできます。
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES=
Collections.unmodifiableList(Arrrays.asList(PRIVATE_VALUES));
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values(){
return PRIVATE_VALUES.clone();
}
댓글 없음:
댓글 쓰기