2018-06-11  Java プログラミング

setter/getterを強制する規約は廃止すべき!?

とある開発プロジェクトに参加したときに こんな Java のコーディング規約に遭遇しました。

インスタンス変数のアクセス修飾子は private とし setter/getter メソッドを実装すること。

この規約は良くないですね……。

Java のインスタンス変数は必ず private にすべし public にするなどありえない。インスタンス変数は setter/getter を通してアクセスする。これがカプセル化というものですよ

このように力説してくれる上級 Java 開発者が一定数います。

しかし 私はずっと疑問に思っていました。クラスとはデータ構造と操作 アルゴリズム を持つもの。操作を持たないデータのみで構成されるものはクラスではなく構造体なのではないか? Java の言語仕様には struct がないから class で代用しているだけではないか? class を構造体として使う場合は setter/getter を設けずに フィールドのアクセス修飾子を public にしてもおかしくないのではないか? と。

あれこれと情報を探してみると 同じことが Stack Overflow でも議論されていました。

この議論の中で クラスが振る舞いを持たず本質的なデータ構造であるなら インスタンス変数を public とするのが適切である Sun Java コード規約に記載されている との回答が付きました。

Java コード規約 10.1 Providing Access to Instance and Class Variables には以下のように記載されていました。

10.1 Providing Access to Instance and Class Variables

Don’t make any instance or class variable public without good reason. Often, instance variables don’t need to be explicitly set or gotten-often that happens as a side effect of method calls.

One example of appropriate public instance variables is the case where the class is essentially a data structure, with no behavior. In other words, if you would have used a struct instead of a class (if Java supported struct), then it’s appropriate to make the class’s instance variables public.

日本語訳は以下の通りです。

10.1 インスタンス変数とクラス変数へのアクセスの提供

正当な理由もなく インスタンス変数やクラス変数を public にしないでください。多くの場合 メソッド呼び出しの副作用としてインスタンス変数の設定や取得がされるので明示的にインスタンス変数を設定 取得する必要がありません。

適切な public インスタンス変数の一つの例は クラスが動作を持たず本質的にデータ構造である場合です。言い換えると 仮に Java struct をサポートしていれば class の代わりに struct を使うという場合 インスタンス変数を public にするのは適切です。

私が感じていた疑問の答えがズバリ書いてありました。Java の言語仕様にはなくとも クラスとは別の概念として構造体を考えることができ そのようなケースではインスタンス変数のアクセス修飾子を public にするのが適切であるということが 20 年前から Java のコード規約には書かれていたのです。

このような動作を持たない本質的データ構造は Passive data structure 受動的なデータ構造 と呼ばれ PDS と略されることもあるそうです。

受動的なデータ構造 PDS 他システムや永続化ストレージ間を移動するデータとしてシステム境界でよく見られます。つまり O/R マッパーを使ってデータベース テーブルの行に対応させるエンティティクラスや JSON データを使ってシリアライズ デシリアライズするデータクラスなどは受動的なデータ構造 PDS と言えます。

このようなクラスにまで杓子定規に setter/getter を実装する必要はなく むしろ インスタンス変数を public にすることが適切であるとされているわけです。

これからは 堂々と 受動的なデータ構造のフィールドを public にしていこうと思います。

最終更新日 2024-12-13
この記事を共有しませんか?
ブックマーク ポスト