1. シングルトン モード
シングルトン モードは、名前が示すように、インスタンスが 1 つだけ存在することを意味します。オブジェクト作成モードとしてのシングルトン モードでは、クラスのインスタンスが 1 つだけであることが保証され、クラス自体がインスタンス化され、このインスタンスがシステム全体に提供されます。
シングルトン パターンの主なポイントは 3 つあります。
まず、クラスはインスタンスを 1 つだけ持つことができます。
2 つ目は、このインスタンスを独自に作成する必要があります。
3 つ目は、このインスタンスを全体に提供する必要があります。システム自体。
PHP シングルトン モードを使用する理由
1. PHP は主にデータベース アプリケーションで使用されます。オブジェクト指向で開発する場合、シングルトン モードを使用すると、次のことが可能になります。大量の操作を回避します。新しい操作ではリソースが消費され、データベース接続が削減されるため、過剰な接続が発生する可能性が低くなります。
2. システム内の特定の構成情報をグローバルに制御するためにクラスが必要な場合は、zend フレームワークの FrontController 部分にあるシングルトン モードを使用して簡単に実装できます。
3. ページリクエストでは、すべてのコード (データベース操作クラス db など) が 1 つのクラスに集中しているため、クラス内でフックを設定し、どこでも var_dump や echo を回避できるため、デバッグが簡単です。
/** * 设计模式之单例模式 * $_instance必须声明为静态的私有变量 * 构造函数必须声明为私有,防止外部程序new类从而失去单例模式的意义 * getInstance()方法必须设置为公有的,必须调用此方法以返回实例的一个引用 * ::操作符只能访问静态变量和静态函数 * new对象都会消耗内存 * 使用场景:最常用的地方是数据库连接。 * 使用单例模式生成一个对象后,该对象可以被其它众多对象所使用。 */ class man { //保存例实例在此属性中 private static $_instance; //构造函数声明为private,防止直接创建对象 private function __construct() { echo '我被实例化了!'; } //单例方法 public static function get_instance() { var_dump(isset(self::$_instance)); if(!isset(self::$_instance)) { self::$_instance=new self(); } return self::$_instance; } //阻止用户复制对象实例 private function __clone() { trigger_error('Clone is not allow' ,E_USER_ERROR); } function test() { echo("test"); } } // 这个写法会出错,因为构造方法被声明为private //$test = new man; // 下面将得到Example类的单例对象 $test = man::get_instance(); $test = man::get_instance(); $test->test(); // 复制对象将导致一个E_USER_ERROR. //$test_clone = clone $test;
/** * * 定义个抽象的类,让子类去继承实现它 * */ abstract class Operation{ //抽象方法不能包含函数体 abstract public function getValue($num1,$num2);//强烈要求子类必须实现该功能函数 } /** * 加法类 */ class OperationAdd extends Operation { public function getValue($num1,$num2){ return $num1+$num2; } } /** * 减法类 */ class OperationSub extends Operation { public function getValue($num1,$num2){ return $num1-$num2; } } /** * 乘法类 */ class OperationMul extends Operation { public function getValue($num1,$num2){ return $num1*$num2; } } /** * 除法类 */ class OperationDiv extends Operation { public function getValue($num1,$num2){ try { if ($num2==0){ throw new Exception("除数不能为0"); }else { return $num1/$num2; } }catch (Exception $e){ echo "错误信息:".$e->getMessage(); } } }
/** * 求余类(remainder) * */ class OperationRem extends Operation { public function getValue($num1,$num2){ return $num1%$num12; } }
解決策: 別のクラスを使用してインスタンス化プロセスを実装します。このクラスがファクトリーです]
/** * 工程类,主要用来创建对象 * 功能:根据输入的运算符号,工厂就能实例化出合适的对象 * */ class Factory{ public static function createObj($operate){ switch ($operate){ case '+': return new OperationAdd(); break; case '-': return new OperationSub(); break; case '*': return new OperationSub(); break; case '/': return new OperationDiv(); break; } } } $test=Factory::createObj('/'); $result=$test->getValue(23,0); echo $result;
交通機関を例に挙げます: お問い合わせください。カスタマイズされた交通手段は、輸送生産のプロセスもカスタマイズできます
1> 輸送をカスタマイズする
1. ツールを提供する方法 (開始、実行、停止) を含むインターフェイスを定義します
2. 飛行機や車などに実装させます
2 > カスタマイズされたファクトリー (上記と同様)
1. デリバリーツールの製造方法 (開始、実行、停止) を含むインターフェースを定義します
2. 航空機と自動車を製造するためのファクトリークラスをそれぞれ作成し、このインターフェースを継承して実装します
class MyObserver1 implements SplObserver { public function update(SplSubject $subject) { echo __CLASS__ . ' - ' . $subject->getName(); } } class MyObserver2 implements SplObserver { public function update(SplSubject $subject) { echo __CLASS__ . ' - ' . $subject->getName(); } } class MySubject implements SplSubject { private $_observers; private $_name; public function __construct($name) { $this->_observers = new SplObjectStorage(); $this->_name = $name; } public function attach(SplObserver $observer) { $this->_observers->attach($observer); } public function detach(SplObserver $observer) { $this->_observers->detach($observer); } public function notify() { foreach ($this->_observers as $observer) { $observer->update($this); } } public function getName() { return $this->_name; } } $observer1 = new MyObserver1(); $observer2 = new MyObserver2(); $subject = new MySubject("test"); $subject->attach($observer1); $subject->attach($observer2);