PHP面向对象程序设计之对象生成方法详解


Posted in PHP onDecember 02, 2016

本文实例讲述了PHP面向对象程序设计之对象生成方法。分享给大家供大家参考,具体如下:

对象

看个例子

<?php
abstract class Employee { // 雇员
  protected $name;
  function __construct( $name ) {
    $this->name = $name;
  }
  abstract function fire();
}
class Minion extends Employee { // 奴隶 继承 雇员
  function fire() {
    print "{$this->name}: I'll clear my desk\n";
  }
}
class NastyBoss { // 坏老板
  private $employees = array();
  function addEmployee( $employeeName ) { // 添加员工
    $this->employees[] = new Minion( $employeeName ); // 代码灵活性受到限制
  }
  function projectFails() {
    if ( count( $this->employees ) > 0 ) {
      $emp = array_pop( $this->employees );
      $emp->fire(); // 炒鱿鱼
    }
  }
}
$boss = new NastyBoss();
$boss->addEmployee( "harry" );
$boss->addEmployee( "bob" );
$boss->addEmployee( "mary" );
$boss->projectFails();
// output:
// mary: I'll clear my desk
?>

再看一个更具有灵活性的案例

<?php
abstract class Employee {
  protected $name;
  function __construct( $name ) {
    $this->name = $name;
  }
  abstract function fire();
}
class Minion extends Employee {
  function fire() {
    print "{$this->name}: I'll clear my desk\n";
  }
}
class NastyBoss {
  private $employees = array(); 
  function addEmployee( Employee $employee ) { // 传入对象
    $this->employees[] = $employee;
  }
  function projectFails() {
    if ( count( $this->employees ) ) {
      $emp = array_pop( $this->employees );
      $emp->fire();
    }
  }
}
// new Employee class...
class CluedUp extends Employee {
  function fire() {
    print "{$this->name}: I'll call my lawyer\n";
  }
}
$boss = new NastyBoss();
$boss->addEmployee( new Minion( "harry" ) ); // 直接以对象作为参数,更具有灵活性
$boss->addEmployee( new CluedUp( "bob" ) );
$boss->addEmployee( new Minion( "mary" ) );
$boss->projectFails();
$boss->projectFails();
$boss->projectFails();
// output:
// mary: I'll clear my desk
// bob: I'll call my lawyer
// harry: I'll clear my desk
?>

单例

<?php
class Preferences {
  private $props = array();
  private static $instance; // 私有的,静态属性
  private function __construct() { } // 无法实例化,私有的构造函数
  public static function getInstance() { // 返回对象 静态方法才可以被类访问,静态方法中要有静态属性
    if ( empty( self::$instance ) ) {
      self::$instance = new Preferences();
    }
    return self::$instance;
  }
  public function setProperty( $key, $val ) {
    $this->props[$key] = $val;
  }
  public function getProperty( $key ) {
    return $this->props[$key];
  }
}
$pref = Preferences::getInstance();
$pref->setProperty( "name", "matt" );
unset( $pref ); // remove the reference
$pref2 = Preferences::getInstance();
print $pref2->getProperty( "name" ) ."\n"; // demonstrate value is not lost
?>

点评:不能随意创建对象,只能通过Preferences::getInstance()来创建对象。

工厂模式

<?php
abstract class ApptEncoder {
  abstract function encode();
}
class BloggsApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in BloggsCal format\n";
  }
}
class MegaApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in MegaCal format\n";
  }
}
class CommsManager { // 负责生产Bloggs对象
  function getApptEncoder() {
    return new BloggsApptEncoder();
  }
}
$obj = new CommsManager();
$bloggs = $obj->getApptEncoder(); // 获取对象
print $bloggs->encode();
?>

output:

Appointment data encoded in BloggsCal format

进一步增加灵活性设置

<?php
abstract class ApptEncoder {
  abstract function encode();
}
class BloggsApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in BloggsCal format\n";
  }
}
class MegaApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in MegaCal format\n";
  }
}
class CommsManager {
  const BLOGGS = 1;
  const MEGA = 2;
  private $mode ;
  function __construct( $mode ) {
    $this->mode = $mode;
  }
  function getHeaderText() {
    switch ( $this->mode ) {
      case ( self::MEGA ):
        return "MegaCal header\n";
      default:
        return "BloggsCal header\n";
    }
  }
  function getApptEncoder() {
    switch ( $this->mode ) {
      case ( self::MEGA ):
        return new MegaApptEncoder();
      default:
        return new BloggsApptEncoder();
    }
  }
}
$man = new CommsManager( CommsManager::MEGA );
print ( get_class( $man->getApptEncoder() ) )."\n";
$man = new CommsManager( CommsManager::BLOGGS );
print ( get_class( $man->getApptEncoder() ) )."\n";
?>

output:

MegaApptEncoder
BloggsApptEncoder

工厂方法模式要把创建者类与要生产的产品类分离开来。

抽象工厂

通过抽象来来约束,成为一定的规矩。

<?php
abstract class ApptEncoder {
  abstract function encode();
}
class BloggsApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in BloggsCal format\n";
  }
}
class MegaApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in MegaCal format\n";
  }
}
abstract class CommsManager { // 预约
  abstract function getHeaderText();
  abstract function getApptEncoder();
  abstract function getTtdEncoder();
  abstract function getContactEncoder();
  abstract function getFooterText();
}
class BloggsCommsManager extends CommsManager {
  function getHeaderText() {
    return "BloggsCal header\n";
  }
  function getApptEncoder() {
    return new BloggsApptEncoder();
  }
  function getTtdEncoder() {
    return new BloggsTtdEncoder();
  }
  function getContactEncoder() {
    return new BloggsContactEncoder();
  }
  function getFooterText() {
    return "BloggsCal footer\n";
  }
}
class MegaCommsManager extends CommsManager {
  function getHeaderText() {
    return "MegaCal header\n";
  }
  function getApptEncoder() {
    return new MegaApptEncoder();
  }
  function getTtdEncoder() {
    return new MegaTtdEncoder();
  }
  function getContactEncoder() {
    return new MegaContactEncoder();
  }
  function getFooterText() {
    return "MegaCal footer\n";
  }
}
$mgr = new MegaCommsManager();
print $mgr->getHeaderText();
print $mgr->getApptEncoder()->encode(); // 对象调用方法,返回对象,继续调用方法。
print $mgr->getFooterText();
?>

output:

MegaCal header
Appointment data encoded in MegaCal format
MegaCal footer

更加牛逼的实现

<?php
// 根据类图,规划类的代码。从大局入手。
abstract class ApptEncoder {
  abstract function encode();
}
class BloggsApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in BloggsCal format\n";
  }
}
class MegaApptEncoder extends ApptEncoder {
  function encode() {
    return "Appointment data encoded in MegaCal format\n";
  }
}
abstract class CommsManager {
  const APPT  = 1;
  const TTD   = 2;
  const CONTACT = 3;
  abstract function getHeaderText();
  abstract function make( $flag_int ); // int标记
  abstract function getFooterText();
}
class BloggsCommsManager extends CommsManager {
  function getHeaderText() {
    return "BloggsCal header\n";
  }
  function make( $flag_int ) {
    switch ( $flag_int ) {
      case self::APPT: // self直接控制常量
        return new BloggsApptEncoder();
      case self::CONTACT:
        return new BloggsContactEncoder();
      case self::TTD:
        return new BloggsTtdEncoder();
    }
  }
  function getFooterText() {
    return "BloggsCal footer\n";
  }
}
$mgr = new BloggsCommsManager();
print $mgr->getHeaderText();
print $mgr->make( CommsManager::APPT )->encode();
print $mgr->getFooterText();
?>

output:

BloggsCal header
Appointment data encoded in BloggsCal format
BloggsCal footer

原型模式

改造成一个保存具体产品的工厂类。

<?php
class Sea {} // 大海
class EarthSea extends Sea {}
class MarsSea extends Sea {}
class Plains {} // 平原
class EarthPlains extends Plains {}
class MarsPlains extends Plains {}
class Forest {} // 森林
class EarthForest extends Forest {}
class MarsForest extends Forest {}
class TerrainFactory { // 地域工厂
  private $sea;
  private $forest;
  private $plains;
  function __construct( Sea $sea, Plains $plains, Forest $forest ) { // 定义变量为类对象
    $this->sea = $sea;
    $this->plains = $plains;
    $this->forest = $forest;
  }
  function getSea( ) {
    return clone $this->sea; // 克隆
  }
  function getPlains( ) {
    return clone $this->plains;
  }
  function getForest( ) {
    return clone $this->forest;
  }
}
$factory = new TerrainFactory( new EarthSea(),
  new EarthPlains(),
  new EarthForest() );
print_r( $factory->getSea() );
print_r( $factory->getPlains() );
print_r( $factory->getForest() );
?>

output:

EarthSea Object
(
)
EarthPlains Object
(
)
EarthForest Object
(
)

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
用PHP产生动态的影像图
Oct 09 PHP
同一空间绑定多个域名而实现访问不同页面的PHP代码
Dec 06 PHP
php win下Socket方式发邮件类
Aug 21 PHP
php和js如何通过json互相传递数据相关问题探讨
Feb 26 PHP
Yii查询生成器(Query Builder)用法实例教程
Sep 04 PHP
PHP读取txt文本文件并分页显示的方法
Mar 11 PHP
php通过文件流方式复制文件的方法
Mar 13 PHP
浅谈PHP实现大流量下抢购方案
Dec 15 PHP
Thinkphp5行为使用方法汇总
Dec 21 PHP
laravel框架查询数据集转为数组的两种方法
Oct 10 PHP
PHP上传图片到数据库并显示的实例代码
Dec 20 PHP
PHP实现考试倒计时功能代码
Apr 16 PHP
PHP面向对象程序设计组合模式与装饰模式详解
Dec 02 #PHP
PHP与jquery实时显示网站在线人数实例详解
Dec 02 #PHP
谈谈php对接芝麻信用踩的坑
Dec 01 #PHP
PHP自定义函数获取汉字首字母的方法
Dec 01 #PHP
phpmailer绑定邮箱的实现方法
Dec 01 #PHP
thinkPHP实现多字段模糊匹配查询的方法
Dec 01 #PHP
thinkPHP商城公告功能开发问题分析
Dec 01 #PHP
You might like
模板引擎正则表达式调试小技巧
2011/07/20 PHP
php递归方法实现无限分类实例代码
2014/02/28 PHP
详谈PHP编码转换问题
2015/07/28 PHP
joomla数据库操作示例代码
2016/01/06 PHP
Yii使用DbTarget实现日志功能的示例代码
2020/07/21 PHP
JavaScript实现禁止后退的方法
2006/12/27 Javascript
页面只能打开一次Cooike如何实现
2012/12/04 Javascript
在JS中如何调用JSP中的变量
2014/01/22 Javascript
深入理解JavaScript系列(40):设计模式之组合模式详解
2015/03/04 Javascript
三分钟带你玩转jQuery.noConflict()
2016/02/15 Javascript
深入剖析JavaScript中的函数currying柯里化
2016/04/29 Javascript
基于JavaScript实现图片剪切效果
2017/03/07 Javascript
Angular.js去除页面中显示的空行方法示例
2017/03/30 Javascript
JavaScript表单验证实现代码
2017/05/22 Javascript
JavaScript实现QQ列表展开收缩扩展功能
2017/10/30 Javascript
vue 本地服务不能被外部IP访问的完美解决方法
2018/10/29 Javascript
JS实现商品橱窗特效
2020/01/09 Javascript
js实现旋转木马轮播图效果
2020/01/10 Javascript
关于vue 结合原生js 解决echarts resize问题
2020/07/26 Javascript
python中实现定制类的特殊方法总结
2014/09/28 Python
Python快速从注释生成文档的方法
2016/12/26 Python
解决python selenium3启动不了firefox的问题
2018/10/13 Python
浅谈pycharm的xmx和xms设置方法
2018/12/03 Python
PyQt5实现类似别踩白块游戏
2019/01/24 Python
含精油的天然有机化妆品:Indemne
2019/08/27 全球购物
如何手工释放资源
2013/12/15 面试题
一份创业计划书范文
2014/02/08 职场文书
企业环保标语
2014/06/10 职场文书
党员四风自我剖析材料思想汇报
2014/09/13 职场文书
应聘教师求职信范文
2015/03/20 职场文书
2015年大班保育员工作总结
2015/05/18 职场文书
车辆管理制度范本
2015/08/05 职场文书
预备党员表决心的话
2015/09/22 职场文书
解析Java异步之call future
2021/06/14 Java/Android
「Manga Time Kirara MAX」2022年5月号封面公开
2022/03/21 日漫
mysql数据库隔离级别详解
2022/06/16 MySQL