PHP面向对象学习笔记之二:生成对象的设计模式

2 篇文章 0 订阅
2 篇文章 0 订阅

一. 单例模式(Singleton)

 如果应用程序每次包含且仅包含一个对象,那么这个对象就是一单例. 用来替代全局变量.

<?php
require_once("DB.php");

class DatabaseConnection{
  public static function get(){
      static $db = null;
    if ( $db == null )
      $db = new DatabaseConnection();
    return $db;
  }

  private $_handle = null;  
  private function __construct() {
    $dsn = 'mysql://root:password@localhost/photos';
    $this->_handle =& DB::Connect( $dsn, array() );
  }
  
  public function handle()
  {
    return $this->_handle;
  }
}

print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
print( "Handle = ".DatabaseConnection::get()->handle()."\n" );
?>


二.工厂方法模式(factory method)
要解决的问题: 1>在代码运行时候才知道要生成的对象类型; 2>对象类型可能要扩充新产品类型; 3>每个产品类型都可以定制特定的功能;
工厂方法模式把创建者类与要生产的产品类分离.创建者是一个工厂类,其中定义了用于生成产品对象的类方法.如果没有提供默认实现,就由创建者类的子类来执行实例化.一般情况下,就是每个创建者类的子类实例化一个相应的产品子类.

工厂模式的优点就在创建对象上。 它的任务就是把对象的创建过程都封装起来,然后返回一个所需要的新类。

想改变对象的结构和建立对象的方式,只需选择对象工厂,对代码的改变只需要一次就够了。( 工厂模式的功能是如此强大, 它处于是应用的底层, 所以在许多其余的复杂模式和应用中它会不停地出现。)不同处理对象,内部自动分流处理,但对用户来说,只有一个方法,简单方便

使用接口方式实践工厂模式的例子:

 
 
  1. interface Hello{  
  2.     function say_hello();  
  3. }  
  4. class English implements Hello{  
  5.     public function say_hello(){  
  6.         echo "Hello!";  
  7.     }  
  8. }  
  9. class Chinese implements Hello{  
  10.     public function say_hello(){  
  11.         echo "你好";  
  12.     }  
  13. }  
  14. class speak{  
  15.     public static function factory($type){  
  16.         if($type == 1) $temp = new English();  
  17.         else if($type == 2) $temp = new Chinese();  
  18.         else{  
  19.             die("Not supported!");  
  20.         }  
  21.         return $temp;  
  22.     }  
  23. }  
  24. $test = Speak::factory(1);  
  25. $test->say_hello();  
在<深入浅出设计模式>中,上面的被称为简单工厂模式,因为这个工厂必须能分辨要生产的全部产品.如果有新的产品,必须对工厂进行对应修改,增加相应的业务逻辑或判断.
简单工厂模式的一个标志就是静态方法实现工厂生产功能.
(不简单的)工厂方法模式: 工厂方法是抽象类或接口,具体工厂实现这个方法(接口),让使用者调用以创建具体产品对象( 每一个产品都有对应的具体工厂)
下面是重写的hello
 //抽象工厂
 interface Speaker{
 	function assignSpeaker();
 }
 //具体工厂1
 class EnglishSpeaker implements Speaker{
 	public function assignSpeaker(){
 		return new English();
 	}
 }
//具体工厂2
 class ChineseSpeaker implements Speaker{
 	public function assignSpeaker(){
 		return new Chinese();
 	}
 }

 //抽象产品
 interface Hello{
 	function say_hello();
 }
//具体产品1
 class English implements Hello{
    public function say_hello(){
        echo "Hello!";
    }
 }
//具体产品2
 class Chinese implements Hello{
    public function say_hello(){
        echo "你好";
    }
 }

使用:
if(!empty($_GET['t'])){
 	switch($_GET['t']){
 		case 1: $temp=new EnglishSpeaker();
 				break;
 		case 2: $temp=new ChineseSpeaker();
 				break;
 	}
 	$man=$temp->assignSpeaker();
 	$man->say_hello();
 }



三.抽象工厂模式(Abstract Factory)
产品族;每个实体工厂负责一个产品族(1,2...)的产品, 而每个产品族又划分出几个不同类别(A,B...)
单从某一个实体工厂看,其实就是一个工厂方法模式
 

如果上面的hello例子,又多出来表达方式,正常和歌唱式表达(2个产品族)

 
//抽象工厂
 abstract class Speaker{
 	const NORMAL =1;
 	const SING =2;
 	abstract function assignSpeaker($flag_int);
 }

 //具体工厂1
 class EnglishSpeaker extends Speaker {

 	public function assignSpeaker($flag_int){
 		switch($flag_int){
 			case self::NORMAL:
 				return new NormalEnglish();
 				break;
 			case self::SING:
 				return new SingEnglish();
 				break;
 		}
 	}
 }
//具体工厂2
 class ChineseSpeaker extends Speaker{
 	public function assignSpeaker($flag_int){
 		switch($flag_int){
 			case self::NORMAL:
 				return new NormalChinese();
 				break;
 			case self::SING:
 				return new SingChinese();
 				break;
 		}
 	}
 }
 //抽象产品
 interface Hello{
 	function say_hello();
 }
//具体产品A1
 class NormalEnglish implements Hello{
    public function say_hello(){
        echo "Hello!";
    }
 }
//具体产品B1
 class NormalChinese implements Hello{
    public function say_hello(){
        echo "你好!";
    }
 }
//具体产品A2
 class SingEnglish implements Hello{
    public function say_hello(){
        echo "Oh, jingle bells, jingle bells, Hello! Hello! Hello!";
    }
 }

//具体产品B2
 class SingChinese implements Hello{
    public function say_hello(){
        echo "叮叮当,叮叮当, 你好!你好!你好!";
    }
 }

使用:
       <pre name="code" class="php">        //根据程序的业务逻辑确定具体工厂
        switch($_GET['language']){
 		case 1: $temp=new EnglishSpeaker();
 				break;
 		case 2: $temp=new ChineseSpeaker();
 				break;
 	}
        //根据程序的业务逻辑确定具体产品,无需关心是哪个具体工厂了,维护性提高
 	$man=$temp->assignSpeaker( $_GET['style']);
        //使用产品,无需关心是哪个具体产品
 	$man->say_hello();

 
 
四.原型模式(Prototype)
使用clone 来复制已存在的具体产品,然后具体产品类本身就成为他们自己生成的基础.
 
 
 


                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值