ホームページ >バックエンド開発 >PHPチュートリアル >PHP設計パターン(3): カプセル化
元のアドレス: PHP デザイン パターン (3): カプセル化
オブジェクト指向プログラミングでは、すべてがオブジェクトであり、オブジェクトのカプセル化はオブジェクト指向プログラミングの重要な部分になっています。 。 C/C++、Java、Python、その他の言語と同様、PHP もカプセル化をサポートしています。
物事のカプセル化とは、物事を抽象化し、抽象的な概念を実現するための具体的な方法を提供することを指します。
発音が難しそうですが、クジラの例で考えてみましょう。
クジラにとって、食べるという行為自体は抽象的な概念であり、具体的にどのように食べるかは噛んで消化するプロセスであり、どのように噛んで消化するかさえ目に見えないからです。外側には、食べるインターフェースだけが見えます。クジラの実装には、食べ方と食べ方だけがカプセル化されています。
消化器系はクジラという物体の中にカプセル化されており、外界からは見えず、クジラ自体にしか見えないとさえ言えます。
他のプログラミング言語と同様、PHP には、プライベート、プロテクト、パブリックという 3 つのパッケージ化概念しかありません。
プライベートの概念は、オブジェクトのみが内部的に表示され、外部からは表示されないということです。次のようなものです。
<?phpclass Whale { private $name; public function __construct() { $this->name = "Whale"; } public function eat($food) { chew($food); digest($food); } private function chew($food) { echo "Chewing " . $food . "\n"; } private function digest($food) { echo "Digest " . $food . "\n"; }}?>
name は whale のプライベート属性であり、chew() と Digest() は whale のプライベート メソッドです。他のクラスの場合 ただし、それらはすべて目に見えません。実は、食べることだけに注目すれば、クジラがどのように食べるのかを気にする必要はありません。
保護の概念は、独自のクラスと継承されたクラスのみが表示されることです。このキーワードの目的は、主にクラス派生の誤用を防ぐことです。また、誤用を防ぐためにサードパーティのライブラリを作成するときにも使用されます。
<?phpabstract class Animal { private $name; abstract public function eat($food); protected function chew($food) { echo "Chewing " . $food . "\n"; } protected function digest($food) { echo "Digest " . $food . "\n"; }}class Whale extends Animal { private $name; public function __construct() { $this->name = "Whale"; } public function eat($food) { chew($food); digest($food); }}?>
クジラクラスは継承により動物クラスの咀嚼方法と消化方法を使用できますが、クジラクラスを継承する他のクラスは動物クラスの咀嚼方法と消化方法を使用できなくなります。保護は、特定の要件を達成するためのプログラミングではなく、オブジェクト指向設計に対して行われます。
パブリックの概念は、どのクラスでも何でも制限なくアクセスできるということなので、ここでは詳しく説明しません。
ゲッターとセッターはアクセサーやミューテーターとも呼ばれ、Java/C# などの言語では get()/set() メソッドとして現れることがよくあります。これら 2 つのことについては多くの議論があります。次のクラスについて考えてみましょう:
<?phpclass Price { public $priceA; public $priceB; public $priceC; ...}?>
Getters/Setter が使用されていない場合、Price クラスへの代入と値の取得は一般的に次のようになります:
<?php $price = new Price(); $price->priceA = 1; $price->priceB = 2; $price->priceC = 3; ... echo $price->priceA; echo $price->priceB; echo $price->priceC; ...?>
しかし、Getter/Setter が使用されている場合は、 Price クラスを使用すると、次のようになります:
<?phpclass Price { private $priceA; private $priceB; private $priceC; public function getPriceA() { return $this->priceA; } public function setPriceA($price) { $this->priceA = $price; } ...}?>
この時点で、割り当ては次のようになります:
<?php $price = new Price(); $price->setpriceA(1); $price->setPriceB(2); $price->setPriceC(3); ... echo $price->getPriceA(); echo $price->getPriceB(); echo $price->getPriceC(); ...?>
さらに多くのコードを入力する必要があるように感じますか?これは、多くのプログラマが get/set の使用に消極的であり、その結果、一見役に立たない冗長なコードが大量に生成される理由でもあります。一見冗長で役に立たないと言われるのはなぜですか?なぜなら、Getter/Setter はプログラミングの設計手法であり、プログラミングの実装手法ではないからです。
オブジェクト指向プログラミングでは、クラス間のアクセス、対話、および更新は、アクセサーとミューテーター、つまりゲッターとセッターを通じて実現される必要があります。直接アクセスおよび変更すると、クラスのカプセル化が破壊されます。
なぜこのデザインが採用されたのですか?なぜなら、プログラミングは現実の問題を抽象化したものであり、プログラミング プロジェクトではプログラマーが神の役割を果たすことが多いからです。
次のシナリオを考えてみましょう。あなたの友人があなたに名前を変更するかどうかを決めるのは、あなたの友人ではなくあなたです。友人のビジョン (つまり、友人のクラス) では、あなたの名前を直接変更することはできません。
ゲッター/セッター以外の設計方法を直接採用すると、実際にはプログラマーが演じる神が現実のルールを変更し、友人があなたの名前を自由に変更できるようになります。これは明らかに不合理です。
優れたプログラミングには合理的なカプセル化が不可欠ですが、すべてがパブリックであり、プログラミングの問題を解決できますが、これはプログラミングの問題を解決する方法ではありません。