【初心者向け】変数は public にしない方がいい理由

ども、ゴコーです。

よくWeb記事などで「変数は public にしない方がいいので」という文を見ることがあると思います。その理由は何でしょうか?

この記事は

  • 変数を public にしない方がいい理由
  • [SerializeField] はどういう場合につけるのか

を知らない方向けの記事です。

スポンサーリンク

変数を public にするとどうなるか

public にすると以下のように扱えます。

  • シリアライズされて、インスペクターに表示できる
  • どのクラスからも中身を見られる
  • どのクラスからも中身を書き換えられる

以下のようなクラスを用意して ObjectA に張り付けると、

そのオブジェクトのインスペクターは、この画像のようになります。

public_0

このように、シリアライズとかは知らないけど変数をインスペクターに表示したい時は public にするわーという初心者の方も多いんじゃないかと思います。

次に先ほどの ClassA にアクセスするクラスを作ります。

public にするということは、このように他のクラスからも自由に読み取り、書き込みアクセスが自由にできるということです。当たり前ですね。

変数を public にすると何が困るのか

ぼくは他のクラスから自由に書き込めることだと思ってます。

具体的にいうと、次のようなケースに対処するのが面倒です。

  • 不正な値の書き込み
  • 変数の扱い方が変わった場合への対処

それぞれ具体例を出してみます。

まず、ゲームのスコアを管理するスコアマネージャー(ScoreManager)、アイテム(ScoreItem) の2クラスを用意します。
スコアマネージャーには Score という public 変数を用意し、アイテムクラスは取得時に一定のスコアを足すものとします。

本来はスコアマネージャーなどのマネージャークラスはインスペクターから設定するのは得策ではありません。しかし本題ではないので今回は割愛します。

最初の例と同じく、 Score は public 変数なので自由に数字を足すことも、引くこともできます。

困るケース1:不正な値の書き込み

ScoreItem のスコアはオブジェクト毎に自由に設定できるようにします。

さて、最初はスコアを増やすアイテムしかなかったのですが、仕様変更がありスコアを減らすアイテムも作ることになりました。しかしスコアの合計がマイナスになるのはおかしいのでチェックするようにします。

ほんの少しの修正ですが例えばさらに仕様変更があり、敵を倒したときにスコアが増える、味方を倒したときはスコアが減るという要素が増えた場合はどうでしょうか。スコアを変更するクラスの数だけ 0 のチェックをしないといけなくなります。

数値だけではなく「本来ありえないことの回避策」をすべての場所で行うのはとても面倒、というかありえません。

困るケース2:変数の扱い方が変わった場合への対処

さらに仕様変更が入ってしまいました。

連続してアイテムを取ったり敵を倒すとテンションが上がり、スコアの増加にプラス補正がかかることになりました。

先ほどよりもがっつりとした変更が入りました。

ではこの変更をスコアを扱うすべてのクラスに施しましょう!……というのは苦行すぎるのでやめましょう。

また、もしもスコアに関するバグが発生した場合スコアを書き換える処理を書いているすべてのクラスを調べなければいけません。すごいですね(白目

処理はできる限りクラス内で収めるべき

このように、 public 変数を公開して他のクラスから自由に書き換えられるようにすると何かと非常にめんどくさいことになります。複数人での開発ともなると地獄しか待っていません。

ではどうするかというと…以下のようにします。

変数を private に変更して [SerializeField] 属性を付け、 スコアへの干渉は AddScore からのみできるようにしました。

get set などが分からないかもしれません。これはプロパティといい、値にアクセスされた瞬間処理が実行されます。詳しくは次回ということで。

結果 ScoreManager は大きくなりましたが、 ScoreItem は同じだけ短くなりました。

この形式の方が良い理由をざっくりまとめると

  • クラスの中身を外部から自由に書き換えられない
  • 不正な値に対処できている
  • バグ発生時チェックしなければいけない箇所が減る

というところです。要求が増えた場合もスコアマネージャーに処理を追加するようにしましょう。

[SerializeField] はどういう場合につけるのか

先ほどのスクリプトを変更する際、 public な変数を private に変更して Serialize 属性をつけました。

Unity は変数をインスペクターに表示する際シリアライズということをするのですが、その方法は2つあります。

  • 変数を public として定義する
  • [SerializeField] を付ける

public にはしたくない場合、 [SerializeField] を付けるしかないということになります。

次回はプロパティについて勉強してみましょう。今回の記事について分かりにくい部分等ありましたらコメントで教えてくださいませー。

では、また。

Comments

comments

スポンサーリンク
336*280px

コメント

  1. @maoh_vel より:

    RT @backlight1144: 新しい記事です: 【初心者向け】変数は public にしない方がいい理由 https://t.co/IVgymajg6M by Unity道しるべ

  2. @namemirage17 より:

    RT @backlight1144: 新しい記事です: 【初心者向け】変数は public にしない方がいい理由 https://t.co/IVgymajg6M by Unity道しるべ

  3. @TAH_iwa より:

    RT @backlight1144: 新しい記事です: 【初心者向け】変数は public にしない方がいい理由 https://t.co/IVgymajg6M by Unity道しるべ