-
-
class SingetonBasic {
- private static $instance;
-
private function __construct() {
- // do construct..
- }
private function __clone() {}
public static function getInstance() {
- if (!(self::$instance instanceof self)) {
- self::$instance = new self();
- }
- return self::$instance;
- }
// other functions..
- }
$a = SingetonBasic ::getInstance();
- $b = SingetonBasic::getInstance();
- var_dump($a === $b);
-
複製代碼
二、工廠模式
工廠模式在於可以根據輸入參數或應用程式配置的不同來創建一種專門用來實現化並傳回其它類別的實例的類別。
工廠模式的例子:
-
-
class FactoryBasic {
- public static function create($config) {
}
- }
-
複製程式碼
例如這裡是一個描述形狀物件的工廠,它希望根據傳入的參數個數不同來創造不同的形狀。
-
-
// 定義形狀的公共功能:取得周長和麵積。
- interface IShape {
- function getCircum();
- function getArea();
- }
// 定義矩形類別
- class Rectangle implements🎜>
// 定義矩形類別
- class Rectangle implements IShape {
- private $width, $height;
public function __construct($width, $height) {
- $this->width = $width;
- $this->height = $height;
- }
public function getCircum() {
- return 2 * ($this->width + $this->height);
- } p>
public function getArea() {
- return $this->width * $this->height;
- }
- }
//定義圓類
- class Circle implements IShape {
- private $radii;
public function __construct($radii) {
- $this->radii = $radii;
- }
public function getCircum() {
- return 2 * M_PI * $this->radii;
- }
public function getArea( ) {
- return M_PI * pow($this->radii, 2);
- }
- }
// 根據傳入的參數個數不同而建立不同的形狀。
- class FactoryShape {
- public static function create() {
- switch (func_num_args()) {
- case 1:
- return new Circle(func_get_arg(0)break;case 2:
- return new Rectangle(func_get_arg(0), func_get_arg(1));
- break;
}
- }
- } p>
// 矩形物件
- $c = FactoryShape::create(4, 2);
- var_dump($c->getArea());
- // 圓形物件
- $o = FactoryShape::create(2);
- var_dump($o->getArea());
-
複製代碼
使用工廠模式使得在呼叫方法時變得更容易,因為它只有一個類別和一個方法,若沒有使用工廠模式,則要在呼叫時決定應該呼叫哪個類別和哪個方法;使用工廠模式也使得未來對應用程式做改變時更加容易,例如要增加一種形狀的支持,只需要修改工廠類別中的create()一個方法,而沒有使用工廠模式,則要修改呼叫形狀的程式碼區塊。
三、觀察者模式
觀察者模式為您提供了避免組件之間緊密耦合的另一種方法。這個模式非常簡單:一個物件透過添加一個方法(該方法允許另一個對象,即觀察者註冊自己)使本身變得可觀察。當可觀察的物件變更時,它會將訊息傳送到已註冊的觀察者。這些觀察者使用該資訊執行的操作與可觀察的物件無關。結果是對象可以相互對話,而不必了解原因。
一個簡單的範例:當聽眾在收聽電台時(即電台加入一個新聽眾),它將發送出一條提示訊息,透過發送訊息的日誌觀察者可以觀察這些訊息。
-
-
// 觀察者介面
- interface IObserver {
- function onListen($sender,ender, $args);
- function getName();
- }
// 可被觀察介面
- interface IObservable {
- function addObserver($observer);function addObserver($observer);function addObserver($observer);function addObserver($observer);function removeObserver($observer_name);
- }
// 觀察者類別
- abstract class Observer implements IObserver {
- protected $name;
-
public function getName() {
- return $this->name;
- }
- }
// 可被觀察類別
- class Observable implements IObservable {
- protected $observers = array();
public function addObserver($observer) {
- if (!($observer instanceof IObserver)) {
- return;
- }
- $this->observers[] = $observer;
- }
public function removeObserver($observer_name) {
- foreach ($this->observers as $index => $observer) {
- if ($observer->getName() === $observer_name) {
- array_splice($this->observers, $index, 1);
- return;
- }
- }
- }
- }
// 模擬一個可以被觀察的類別:RadioStation
- class RadioStation extends Observable {
public function addListener($listener) {
- foreach ($this->observers as $observer) {
- $observer->onListen($this, $listener);
- }
- }
- }
// 模擬一個觀察者類別
- class RadioStationLogger extends Observer {
- protected $name = 'logger';
public function onListen($sender, $args) {
- echo $args, ' join the radiostation.
';
- }
- }
//模擬另外一個觀察者類別
- class OtherObserver extends Observer {
- protected $name = 'other';
- public function onListen($sender, $args) {
- echo 'other observer..
';
- }
- }
$rs = new RadioStation();
// 注入觀察者
- $rs ->addObserver(new RadioStationLogger());
- $rs->addObserver(new OtherObserver());
// 移除觀察者
- $rs->removeObserver( 'other');
// 可以看到觀察到的資訊
- $rs->addListener('cctv');
?>
複製程式碼 |