🦍

getter/setterは、ほとんど不要!!?

2022/09/18に公開1

カプセル化

getter/setterの話をする前に、カプセル化について話します。
例えば、ある人間のクラスがあるとします。

public class Human {
    public String name;
    public int age;
    public int cresit_card_number;

    public Human(String name, int age, int cresit_card_number) {
        this.name = name;
        this.age = age;
        this.cresit_card_number = cresit_card_number;
    }
}

Human nana = new Human("nana", 18, 123456789);
nana.cresit_card_number = 987654321;

この状態だと、nanaちゃんのクレジットカード番号はすぐに変更できてしまいます。
それを阻止するためにはprivateを使います。

public class Human {
    private String name;
    private int age;
    private int cresit_card_number;

    public Human(String name, int age, int cresit_card_number) {
        this.name = name;
        this.age = age;
        this.cresit_card_number = cresit_card_number;
    }
}

Human nana = new Human("nana", 18, 123456789);
//エラー
nana.cresit_card_number = 987654321;

setter/getter

privateの時にメンバ変数の値を参照したり、変更したりするものがgetter/setterでしたね。

public class Human {
    private String name;
    private int age;
    private int cresit_card_number;

    public Human(String name, int age, int cresit_card_number) {
        this.name = name;
        this.age = age;
        this.cresit_card_number = cresit_card_number;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Human nana = new Human("nana", 18, 123456789);
nana.setName("nanako");
System.out.println(nana.getName());

getter/setterを使えば、privateなnanaちゃんの情報を参照したり、変更したりできます。

setter/getterが不要な理由

例として、nanaちゃんが大人かどうか判定するプログラムを組んでみます。

public class Human {
    private String name;
    private int age;

    public Human(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }
}

Human nana = new Human("nana", 18);
Boolean isAdult = false;
if (nana.getAge() >= 18) {
    isAdult = true;
}
System.out.println(isAdult);

これで、やりたいことはできます。
これをgetterを使わずに書いて見ます。

public class Human {
    private String name;
    private int age;

    public Human(String name, int age, int cresit_card_number) {
        this.name = name;
        this.age = age;
    }

    public Boolean isAdult() {
        return this.age >= 18 ? true : false;
    }
}

Human nana = new Human("nana", 18);
System.out.println(nana.isAdult());

これで、同じく年齢を判定して、大人か否か判定できています。

ではなぜ後者のgetterを使わないほうが良いとされるのか

例えば、大人判定が18歳から20歳になった場合を考えてみましょう。
前者のgetterを使う方法だと、getterを使っているところすべてを書き換えなくてはいけません。バグにつながりやすいですね。

後者ではのクラス内のメソッドを書き換えれば、完了です。

実務でプログラムを書く場合は、こういったことがよくあるので、なるべく、getter/setterは使わないでプログラムを組んだほうがいいと思いました。

Discussion

kobayashi keikobayashi kei

記事読ませていただきました!
質問なのですが、
大人判定の例ではクラスにisAdult()のようなメソッドを用意しておくことで、
変更が容易だというのは分かるのですが、setter/getterに加えてそのようなメソッドを書いておけばいいだけで、setter/getterが不要だという理由にはならないと思いました。
どうでしょうか?

ログインするとコメントできます