It seems like these interfaces are pretty much useless for any real world problem. Can someone enlighten me?
インターフェース
抽象クラスではある程度の実装を提供できますが、インターフェースは純粋なテンプレートです。缶interface
のみ。define functionality
それを実装することはできません。インターフェイスは、interface キーワードで宣言されます。プロパティとメソッド宣言を含めることができますが、メソッド本体を含めることはできません。
インターフェースのユースケース
たとえば、プロジェクトが異なるデータベースをサポートする必要がある場合。将来データベースを変更できるようにするには、オブジェクトを変更せずに、クラス ファイルにプロパティ プロシージャを含むインターフェイスを使用することをお勧めします
By itself, interfaces are not very useful
インターフェイスのインスタンスを作成することはできませんがwhich in real sense makes your live easier as a programmer
、オブジェクト指向プログラミングの最も重要なインセンティブはカプセル化であるため、インターフェイスはオブジェクト指向の設計方法論を実施するのに役立ちます (機能がどのように実装されているかは気にしません。プログラマーは、これは、システム アーキテクチャを監視する良い方法でもあります)。
SplSubject & SplObserver
直交性は美徳です。プログラマーとしての目的の 1 つは、他のコンポーネントへの影響を最小限に抑えて変更または移動できるコンポーネントを構築することです。
1 つのコンポーネントに加えたすべての変更が、コードベースの別の場所での変更の波及を必要とする場合、開発タスクはすぐにバグの作成と削除のスパイラルになる可能性があります。
SplSubjectとSplObserverは両方であるため、特別な機能はありません。interface to implement the Observer Design Pattern.
オブザーバーパターン
オブザーバー パターンは、サブジェクトと呼ばれるオブジェクトがオブザーバーと呼ばれるその従属オブジェクトのリストを維持し、通常はメソッドの 1 つを呼び出すことによって、状態の変化を自動的に通知するソフトウェア設計パターンです。主に分散イベント処理システムの実装に使用されます
- オブザーバー パターンは、サブジェクト オブジェクトと任意の数のオブザーバー オブジェクトとの間の 1 対多の依存関係を定義するため、サブジェクト オブジェクトの状態が変化すると、そのすべてのオブザーバー オブジェクトに通知が送信され、自動的に更新されます。
- オブザーバー パターンでは、基本的に、オブジェクト自体を登録することにより、無制限の数のオブジェクトが監視対象オブジェクト (またはサブジェクト) 内のイベントを監視またはリッスンできます。オブザーバーがイベントに登録された後、サブジェクトはイベントが発生したときにオブザーバーに通知します。
- サブジェクトは、各オブザーバーに通知するために、オブザーバー コレクションを格納し、イベントが発生したときにそれを反復処理することで、これを処理します。
- オブザーバー パターンは、オブザーバーをサブジェクトに登録します。
- 複数のオブザーバーがいる場合があります。サブジェクトは、登録済みオブザーバーのリストを保持する必要があり、イベントが発生すると、すべての登録済みオブザーバーを起動 (通知を提供) します。
- オブザーバーが不要な場合は、登録解除も可能です。
例 1. ローンの金利通知システム
$loan = new Loan("Mortage", "Citi Bank", 20.5);
$loan->attach(new Online());
$loan->attach(new SMS());
$loan->attach(new Email());
echo "<pre>";
$loan->setIntrest(17.5);
出力
Online : Post online about modified Intrest rate of : 17.50
Send SMS : Send SMS to premium subscribers : 17.50
Send Email: Notify mailing list : 17.50
例 2. シンプルなユーザー登録モニター
$users = new Users();
new Audit($users);
new Logger($users);
new Security($users);
$users->addUser("John");
$users->addUser("Smith");
$users->addUser("Admin");
出力
Audit : Notify Audit about John
Log : User John Create at Wed, 12 Dec 12 12:36:46 +0100
Audit : Notify Audit about Smith
Log : User Smith Create at Wed, 12 Dec 12 12:36:46 +0100
Audit : Notify Audit about Admin
Log : User Admin Create at Wed, 12 Dec 12 12:36:46 +0100
Security : Alert trying to create Admin
オブザーバー デザイン パターンの利点:
主な利点は、オブザーバーとオブザーバブルと呼ばれるオブジェクト間の疎結合です。サブジェクトはオブザーバーのリストを知っているだけで、オブザーバーがどのように実装されているかは気にしません。すべてのオブザーバーは、ブロードキャスト通信として単一のイベント呼び出しでサブジェクトから通知されます。
オブザーバー デザイン パターンの欠点:
- 欠点は、何らかの問題が発生した場合、デバッグが非常に困難になることです。これは、制御の流れがオブザーバーとオブザーバブルの間で暗黙的に行われるため、オブザーバーが起動することを予測でき、オブザーバー間にチェーンがある場合はデバッグがより複雑になることです。
- もう 1 つの問題は、大規模なオブザーバーを扱う場合のメモリ管理です。
共通クラス
abstract class Observable implements SplSubject {
protected $_observers = [];
public function attach(SplObserver $observer) {
$id = spl_object_hash($observer);
$this->_observers[$id] = $observer;
}
public function detach(SplObserver $observer) {
$id = spl_object_hash($observer);
if (isset($this->_observers[$id])) {
unset($this->_observers[$id]);
}
}
public function notify() {
foreach ( $this->_observers as $observer ) {
$observer->update($this);
}
}
}
abstract class Observer implements SplObserver {
private $observer;
function __construct(SplSubject $observer) {
$this->observer = $observer;
$this->observer->attach($this);
}
}
サンプル クラスの読み込み
class Loan extends Observable {
private $bank;
private $intrest;
private $name;
function __construct($name, $bank, $intrest) {
$this->name = $name;
$this->bank = $bank;
$this->intrest = $intrest;
}
function setIntrest($intrest) {
$this->intrest = $intrest;
$this->notify();
}
function getIntrest() {
return $this->intrest;
}
}
class Online implements SplObserver {
public function update(SplSubject $loan) {
printf("Online : Post online about modified Intrest rate of : %0.2f\n",$loan->getIntrest());
}
}
class SMS implements SplObserver {
public function update(SplSubject $loan) {
printf("Send SMS : Send SMS to premium subscribers : %0.2f\n",$loan->getIntrest());
}
}
class Email implements SplObserver {
public function update(SplSubject $loan) {
printf("Send Email: Notify mailing list : %0.2f\n",$loan->getIntrest());
}
}
ユーザー登録のサンプル クラス
class Users extends Observable {
private $name;
function addUser($name) {
$this->name = $name;
$this->notify();
}
function getName() {
return $this->name;
}
}
class Audit extends Observer {
public function update(SplSubject $subject) {
printf("Audit : Notify Autify about %s\n", $subject->getName());
}
}
class Logger extends Observer {
public function update(SplSubject $subject) {
printf("Log : User %s Create at %s\n", $subject->getName(),date(DATE_RFC822));
}
}
class Security extends Observer {
public function update(SplSubject $subject) {
if($subject->getName() == "Admin")
{
printf("Security : Alert trying to create Admin\n");
}
}
}