情報隠蔽
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 41/91。
情報隠蔽はカプセル化の背後にある原則です。これは、クラスが必要なものだけを公開し、内部の実装の詳細を隠すべきであるという考え方です。アクセス修飾子やゲッター/セッターはツールですが、情報隠蔽はそれらをどのように使用するかを導く設計思想です。
目的は、クラスが何をするか(パブリックインターフェース)と、それをどのように行うか(内部実装)の間に明確な境界を作ることです。この分離により、クラスを使用するコードに影響を与えることなく、内部の仕組みを変更できるようになります:
<?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 = 77Fこのクラスは内部的に温度を摂氏で保存しますが、ユーザーがこれを知る必要はありません。後で内部の保存形式を華氏やケルビンに変更することも可能であり、パブリックメソッドが同じように動作し続ける限り、外部のコードが壊れることはありません。
重要なポイント: 情報隠蔽は、コードを修正から保護します。実装の詳細を隠し、安定したインターフェースのみを公開することで、クラスの保守や将来的な変更が容易になります。
チャレンジ
簡単情報の隠蔽(カプセル化)を実践する通貨コンバーターを作成しましょう。内部的には1つの通貨で金額を保持しながら、外部のコードにデータの実際の保存方法を意識させることなく、複数の通貨間でシームレスに変換できるクラスを作成します。
コードは2つのファイルに分けて構成します:
Money.php— 浮動小数点の精度問題を避けるために、すべての金額を内部的にセント(整数)として保存するMoneyクラスを作成します。この実装の詳細は、クラスの利用者から完全に隠蔽される必要があります。クラスには以下のものを用意してください:- 金額をセントで保存するための private プロパティ
setDollars(float $amount)— ドル額を受け取り、内部的にセントとして保存しますgetDollars()— 金額をドルとして返します(float、小数点以下2桁)setEuros(float $amount)— ユーロを受け取り、1 EUR = 1.10 USD のレートを使用してセントに変換しますgetEuros()— ユーロに変換された金額を返します(float、小数点以下2桁)getInternalValue()— デバッグ用に生のセント値(整数)を返します
main.php— Money ファイルをインクルードします。ドル額とユーロ額の2つの入力を受け取ります。Moneyインスタンスを作成してください。まず、ドル額(floatに変換したもの)を設定し、ドル値、ユーロ換算値、および内部のセント値の3行を出力します。次に、ユーロ額(floatに変換したもの)を設定し、同じ3つの値を再度出力します。
この設計の素晴らしい点は、外部のコードが使い慣れたドルやユーロの値を扱いつつ、内部ですべてがセントとして保存されていることを完全に意識せずに済むことです。後で内部ストレージを別の基準通貨や異なる精度戦略を使用するように変更したとしても、パブリックメソッドが正しく機能し続ける限り、外部のコードを変更する必要はありません。
ドルとユーロの出力はすべて、正確に小数点以下2桁にフォーマットしてください。各値はそれぞれの行に出力し、合計6行の出力になるようにします。
チートシート
情報隠蔽はカプセル化の背後にある原則であり、内部の実装の詳細を隠しながら、必要なものだけを公開します。これにより、クラスが何をするか(パブリックインターフェース)と、それをどのように行うか(内部実装)の間に明確な境界が生まれます。
Temperatureクラスを使用した情報隠蔽の例:
<?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 = 77F
このクラスは内部的に温度を摂氏(Celsius)で保存していますが、ユーザーがそれを知る必要はありません。パブリックメソッドが同じように機能し続ける限り、外部のコードを壊すことなく、内部の保存形式を華氏(Fahrenheit)やケルビン(Kelvin)に変更することができます。
主な利点: 情報隠蔽はコードを修正から保護します。実装の詳細を隠し、安定したインターフェースのみを公開することで、クラスの保守や長期的な変更が容易になります。
自分で試してみよう
<?php
require_once 'Money.php';
// 入力を読み込む
$dollarAmount = floatval(trim(fgets(STDIN)));
$euroAmount = floatval(trim(fgets(STDIN)));
// TODO: Money インスタンスを作成する
// TODO: ドル額を設定し、以下を出力する:
// - ドル値 (小数点以下2桁)
// - ユーロ換算値 (小数点以下2桁)
// - 内部のセント値 (整数)
// TODO: ユーロ額を設定し、以下を出力する:
// - ドル値 (小数点以下2桁)
// - ユーロ換算値 (小数点以下2桁)
// - 内部のセント値 (整数)
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。