Java 基礎からマスターまで — 第3回
オブジェクト、カプセル化、不変値の設計
本ブログ作成文は、講義を目指して製作されました。 また、作成された文章の情報も間違っている可能性がありますので、ご注意ください。
オブジェクトは、関連する状態と動作を1つの境界内に結び付けます。 フィールドを無条件に隠すのではなく、有効な状態だけを作成できるようにルールをクラスに置くことがカプセル化される。
コンストラクタで有効なオブジェクトを作成する
public final class Player {
private final String name;
private int health;
public Player(String name, int health) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("name is required");
}
this.name = name;
this.health = Math.max(0, health);
}
public void takeDamage(int amount) {
if (amount > 0) {
health = Math.max(0, health - amount);
}
}
public int getHealth() {
return health;
}
}
外部が健康を直接変えることはできず、takeDamageという規則を通してのみ変更します。 コンストラクタが終わったオブジェクトは、名前と体力が有効であるという条件を満たします。
参照は同じオブジェクトを指すことができます
Player first = new Player("Rose", 100);
Player second = first;
second.takeDamage(20);
System.out.println(first.getHealth()); // 80
secondにオブジェクトが複製されたのではなく、同じPlayerを指す参照がコピーされた。 独立したコピーが必要な場合は、どのフィールドをコピーするかを明示的に設計する必要があります。
不変値の作成
public final class ItemKey {
private final int id;
private final String grade;
public ItemKey(int id, String grade) {
this.id = id;
this.grade = grade;
}
}
フィールドを final にして変更メソッドを指定しないと、生成後の状態は変わりません。 ただし、フィールドが変更可能なコレクションである場合は、防御コピーまたは読み取り専用ビューまで考慮する必要があります。
オブジェクト設計の鍵は、ゲッターとセッターの両方を作成することではありません。 誰が状態を変えることができ、どの条件が常に維持されるべきかをクラスのパブリックメソッドで表現することです。