庆祝中华人民共和国成立70周年

高举旗帜 团结一致 锐意进取

学习笔记:php常用设计模式

1.单例模式

在应用程序中只存在一个实例,常住内存,适合做数据库类。

单例类只能由自身实例化,所以构造函数应标记为private。

需要一个私有变量用以保存实例和公开一个能访问实例的公开静态方法

/**
* Singleton of Database
*/
class Database
{
  // We need a static private variable to store a Database instance.
  privatestatic $instance;
 
  // Mark as private to prevent it from being instanced.
  private function__construct()
  {
    // Do nothing.
  }
 
  private function__clone() 
  {
    // Do nothing.
  }
 
  public static function getInstance() 
  {
    if (!(self::$instance instanceof self)) {
      self::$instance = new self();
    }
 
    return self::$instance;
  }
}
 
$a =Database::getInstance();
$b =Database::getInstance();
 
// true
var_dump($a === $b);

// Mark as private to prevent it from being instanced.
private function__construct()
{
// Do nothing.
}

private function__clone()
{
// Do nothing.
}

public static function getInstance()
{
if (!(self::$instance instanceof self)) {
self::$instance = new self();
}

return self::$instance;
}
}

$a =Database::getInstance();
$b =Database::getInstance();

// true
var_dump($a === $b);

2.工厂设计模式

根据参数的不同 实例化不同的类并返回

interface InterfaceShape { function getArea(); function getCircumference(); } /** * 矩形 */ class Rectangle implements InterfaceShape { private $width; private $height; public function __construct($width, $height) { $this->width = $width;
    $this->height = $height;
  }
 
  public function getArea() 
  {
    return $this->width* $this->height;
  }
 
  public function getCircumference()
  {
    return 2 * $this->width + 2 * $this->height;
  }
}
 
/**
* 圆形
*/
class Circle implements InterfaceShape
{
  private $radius;
 
  function __construct($radius)
  {
    $this->radius = $radius;
  }
 
 
  public function getArea() 
  {
    return M_PI * pow($this->radius, 2);
  }
 
  public function getCircumference()
  {
    return 2 * M_PI * $this->radius;
  }
}
 
/**
* 形状工厂类
*/
class FactoryShape 
{ 
  public static function create()
  {
    switch (func_num_args()) {
      case 1:
      return new Circle(func_get_arg(0));
      case 2:
      return new Rectangle(func_get_arg(0), func_get_arg(1));
      default:
        # code...
        break;
    }
  } 
}
 
$rect =FactoryShape::create(5, 5);
var_dump($rect->getArea());
echo "
";
 
$circle =FactoryShape::create(4);
var_dump($circle);

public function getArea()
{
return $this->width* $this->height;
}

public function getCircumference()
{
return 2 * $this->width + 2 * $this->height;
}
}

/**
* 圆形
*/
class Circle implements InterfaceShape
{
private $radius;

function __construct($radius)
{
$this->radius = $radius;
}

public function getArea()
{
return M_PI * pow($this->radius, 2);
}

public function getCircumference()
{
return 2 * M_PI * $this->radius;
}
}

/**
* 形状工厂类
*/
class FactoryShape
{
public static function create()
{
switch (func_num_args()) {
case 1:
return new Circle(func_get_arg(0));
case 2:
return new Rectangle(func_get_arg(0), func_get_arg(1));
default:
# code…
break;
}
}
}

$rect =FactoryShape::create(5, 5);
var_dump($rect->getArea());
echo "
";

$circle =FactoryShape::create(4);
var_dump($circle);

 

3.观察者模式

 主题类在进行操作时通过接口通知观察者,让观察者来实现某些业务逻辑
观察者模式典型实现方式:
 1、定义2个接口:观察者(通知)接口、被观察者(主题)接口
 2、定义2个类,观察者对象实现观察者接口、主题类实现被观者接口
 3、主题类注册自己需要通知的观察者
 4、主题类某个业务逻辑发生时通知观察者对象,每个观察者执行自己的业务逻辑。
#===================定义观察者、被观察者接口============
/**
 * 
 * 观察者接口(通知接口)
 * 
 */
interface ITicketObserver //观察者接口
{
    function onBuyTicketOver($sender, $args); //得到通知后调用的方法
}
 
/**
 * 
 * 主题接口
 *
 */
interface ITicketObservable //被观察对象接口
{
    function addObserver($observer); //提供注册观察者方法
}
#====================主题类实现========================
/**
 * 
 * 主题类(购票)
 *
 */
class HipiaoBuy implements ITicketObservable { //实现主题接口(被观察者)
    private $_observers = array (); //通知数组(观察者)
    
 
    public function buyTicket($ticket) //购票核心类,处理购票流程
    {
       // TODO 购票逻辑
       //循环通知,调用其onBuyTicketOver实现不同业务逻辑
       foreach ( $this->_observers as $obs )
           $obs->onBuyTicketOver ( $this, $ticket ); //$this 可用来获取主题类句柄,在通知中使用
    }
    
    //添加通知
    public function addObserver($observer) //添加N个通知
    {
       $this->_observers [] = $observer;
    }
}
 
#=========================定义多个通知====================
//短信日志通知
class HipiaoMSM implements ITicketObserver {
    public function onBuyTicketOver($sender, $ticket) {
       echo (date ( 'Y-m-d H:i:s' ) . " 短信日志记录:购票成功:$ticket
");
    }
}
//文本日志通知
class HipiaoTxt implements ITicketObserver {
    public function onBuyTicketOver($sender, $ticket) {
       echo (date ( 'Y-m-d H:i:s' ) . " 文本日志记录:购票成功:$ticket
");
    }
}
//抵扣卷赠送通知
class HipiaoDiKou implements ITicketObserver {
    public function onBuyTicketOver($sender, $ticket) {
       echo (date ( 'Y-m-d H:i:s' ) . " 赠送抵扣卷:购票成功:$ticket 赠送10元抵扣卷1张。
");
    }
}
#============================用户购票====================
$buy = new HipiaoBuy ();
$buy->addObserver ( new HipiaoMSM () ); //根据不同业务逻辑加入各种通知
$buy->addObserver ( new HipiaoTxt () );
$buy->addObserver ( new HipiaoDiKou () );
//购票
$buy->buyTicket ( "一排一号" );
?>

4.适配器模式

将不同类的接口 统一封装成一样的接口

//适配目标,规定的接口将被适配对象实现
interface IDatabase
{
  public function connect($host, $username, $password, $database);
  public function query($sql);
}
 
//适配器
class Mysql implements IDatabase
{
  protected $connect;
 
  public function connect($host, $username, $password, $database)
  {
    $connect = mysql_connect($host, $username, $password);
    mysql_select_db($database, $connect);
    $this->connect = $connect;
    //...
  }
 
  public function query($sql)
  {
    //...
  }
}
 
//适配器
class Postgresql implements IDatabase
{
  protected $connect;
 
  public function connect($host, $username, $password, $database)
  {
    $this->connect = pg_connect("host=$host dbname=$database user=$username password=$password");
    //...
  }
 
  public function query($sql)
  {
    //...
  }
}
 
 
//客户端使用
$client = new Postgresql();
$client->query($sql);

//适配器
class Mysql implements IDatabase
{
protected $connect;

public function connect($host, $username, $password, $database)
{
$connect = mysql_connect($host, $username, $password);
mysql_select_db($database, $connect);
$this->connect = $connect;
//…
}

public function query($sql)
{
//…
}
}

//适配器
class Postgresql implements IDatabase
{
protected $connect;

public function connect($host, $username, $password, $database)
{
$this->connect = pg_connect("host=$host dbname=$database user=$username password=$password");
//…
}

public function query($sql)
{
//…
}
}

//客户端使用
$client = new Postgresql();
$client->query($sql);

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注