情報隠蔽
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 41/91。
情報隠蔽はカプセル化の根底にある原則です。つまり、class は必要なものだけを公開し、internal な実装の詳細を隠すべきだという考え方です。アクセス修飾子とゲッター/セッターがツールであるのに対し、情報隠蔽はそれらの使い方を導く設計思想です。
目標は、class が行うこと(その public interface)と、それをどのように行うか(その internal implementation)の間に、明確な境界を作ることです。この分離により、class を使用するコードに影響を与えずに、internal の仕組みを変更できます。
<?php
class Temperature {
private float $celsius;
public function setCelsius(float $value): void {
$this->celsius = $value;
}
public function getCelsius(): float {
return $this->celsius;
}
public function getFahrenheit(): float {
return ($this->celsius * 9/5) + 32;
}
}
$temp = new Temperature();
$temp->setCelsius(25);
echo $temp->getCelsius() . "C = " . $temp->getFahrenheit() . "F";
出力:
25C = 77FThe class は温度を internally 摂氏で保存しますが、ユーザーがこれを知る必要はありません。後から internal の保存方式を華氏やケルビンに変更しても、public メソッドが同じように動作する限り、外部コードが壊れることはありません。
重要なポイント:情報隠蔽によって、コードを変更から保護できます。実装の詳細を隠し、安定したインターフェースだけを公開すれば、クラスは時間が経っても保守や変更を行いやすくなります。
チャレンジ
簡単実際の情報隠蔽を示す通貨コンバーターを構築しましょう。Money を内部で1つの通貨として保持しながら、外部のコードにデータが実際にどのように保存されているかを知られることなく、複数の通貨との間でシームレスに変換できる class を作成します。
コードを2つのファイルに分けて整理します。
Money.php: すべての金額を cents(integer)として内部に保存するMoneyclass を Create します。これにより、浮動小数点の精度に関する問題を回避できます。この実装の詳細は、class の利用者から完全に隠されるべきです。class には次の機能を用意します。- 金額を cents として保存する private property
setDollars(float $amount): dollar amount を受け取り、内部では cents として保存するgetDollars(): 金額を dollars(float、2 decimal places)として返すsetEuros(float $amount): euros を受け取り、Rate 1 EUR = 1.10 USD を使用して cents に変換するgetEuros(): 金額を euros(float、2 decimal places)に変換して返すgetInternalValue(): debugging 用に raw の cents 値(integer)を返す
main.php: Money file を Include します。2つの inputs、つまり dollar amount と euro amount を受け取ります。Moneyinstance を Create します。まず dollar amount(float に変換済み)を set し、dollars value、euros equivalent、internal cents value の3行を print します。次に euro amount(float に変換済み)を set し、同じ3つの値をもう一度 print します。
この設計の利点は、外部のコードが使い慣れた dollar と euro の値を扱い、すべてが内部では cents として保存されていることを完全に意識せずに済む点です。後から internal storage を別の base currency や異なる precision strategy に変更することもできます。public methods が引き続き正しく動作する限り、外部のコードを変更する必要はありません。
すべての dollar と euro の出力を正確に2 decimal places に Format してください。各値はそれぞれ独立した行に print し、合計6行の Output になるようにします。
自分で試してみよう
<?php
require_once 'Money.php';
// 入力を読み取る
$dollarAmount = floatval(trim(fgets(STDIN)));
$euroAmount = floatval(trim(fgets(STDIN)));
// TODO: Money インスタンスを作成する
// TODO: ドル金額を設定して出力する:
// - ドルの値(小数点以下2桁)
// - ユーロ換算値(小数点以下2桁)
// - 内部のセント値(整数)
// TODO: ユーロ金額を設定して出力する:
// - ドルの値(小数点以下2桁)
// - ユーロ換算値(小数点以下2桁)
// - 内部のセント値(整数)
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: PHPオンラインコンパイラ