はじめに
カプセル化について整理する。
カプセル化とは
クラスの機能のうち使い手に必要ないものを隠すこと。
アクセサーメソッド
カプセル化の典型例として、プロパティを隠蔽するためにアクセサーメソッドを使用する例。
セッター(setBase
, setHeight
)では与えられた引数が負数の場合には例外を発生させている。
TriangleFigure.php
<?php
class TriangleFigure
{
private float $base;
private float $height;
public function __construct()
{
$this->setBase(1);
$this->setHeight(1);
}
public function getBase(): float
{
return $this->base;
}
public function setBase(float $base): void
{
if ($base <= 0) {
throw new Exception('baseは整数で指定します。');
}
$this->base = $base;
}
public function getHeight(): float
{
return $this->height;
}
public function setHeight(float $height): void
{
if ($height <= 0) {
throw new Exception('heightは整数で指定します。');
}
$this->height = $height;
}
public function getArea(): float
{
return $this->base * $this->height / 2;
}
}
なぜアクセサーメソッドを使うのか
アクセサーメソッドを使わずに、プロパティにそのまま外からアクセスできると以下のような弊害がある。
読み書きの許可/禁止を制御できない
プロパティはインスタンスの状態を管理するための変数であるため、取得や変更に何らかの制限を課したい。
プロパティがpublicだと外から自由に取得/変更できてしまう。
値の妥当性を検証できない
型宣言で一定のガードは掛けられるが、詳細なチェックを課すことができない。
外からプロパティを参照するメソッドにチェックを課すことはできるが、これはコードの保守性から望ましくない。
内部状態の変更に左右される
外からプロパティを参照するメソッドが複数ある場合、プロパティの状態を変更すると(型をfloatからintに変えたり等)、そのプロパティを参照する全てのメソッドが影響を受けてしまう。