对象

看个例子

<?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面向对象深入研究之【对象生成】的更多相关文章

  1. [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示

    javascript面向对象编程方式,对于初学者来说,会比较难懂. 要学会面向对象以及使用面向对象编程,理解对象的创建在内存中的表示,至关重要. 首先,我们来一段简单的对象创建代码 var obj = ...

  2. AOP代理对象生成

    AOP(Aspect-OrientedProgramming,面向方面编程)是OOP(Object-Oriented Programing,面向对象编程)的良好补充与完善,后者侧重于解决 从上到下的存 ...

  3. php开发面试题---php面向对象详解(对象的主要三个特性)

    php开发面试题---php面向对象详解(对象的主要三个特性) 一.总结 一句话总结: 对象的行为:可以对 对象施加那些操作,开灯,关灯就是行为. 对象的形态:当施加那些方法是对象如何响应,颜色,尺寸 ...

  4. 03.JavaScript 面向对象精要--理解对象

    JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次 ...

  5. PHP“Cannot use object of type stdClass as array” (php在调用json_decode从字符串对象生成json对象时的报错)

    php再调用json_decode从字符串对象生成json对象时,如果使用[]操作符取数据,会得到下面的错误 错误:Cannot use object of type stdClass as arra ...

  6. java class加载机制及对象生成机制

    java class加载机制及对象生成机制 当使用到某个类,但该类还未初始化,未加载到内存中时会经历类加载.链接.初始化三个步骤完成类的初始化.需要注意的是类的初始化和链接的顺序有可能是互换的. Cl ...

  7. C++面向对象程序设计之类和对象的特性

    类和对象的属性 注意:本文为书籍摘要版,适合有一定程序基础的人阅读. 2.1 面向对象程序设计方法概述 2.1.1 什么是面向对象的程序设计 1.对象 客观世界中的任何一个事物都可以看成一个对象. 如 ...

  8. 深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...

  9. Python记录14:面向对象编程 类和对象

    '''现在主流的编程思想有两种,一种是面向对象,一种是面向过程面向过程编程 核心是过程二字,过程指的是解决问题的步骤,即先干什么.再干什么.最后干什么... 基于该思想编写程序就好比再设计一条流水线, ...

  10. oop面向对象【类与对象、封装、构造方法】

    今日内容 1.面向对象 2.类与对象 3.三大特征——封装 4.构造方法 教学目标 1.能够理解面向对象的思想 2.能够明确类与对象关系 3.能够掌握类的定义格式 4.能够掌握创建对象格式,并访问类中 ...

随机推荐

  1. 使用Entity Framework时遇到的各种问题总结

    在这里记录一下之前使用Entity Framework(4.3.1版本)遇到的问题. 更新没有设置主键的表 在默认情况下,EF不能对一个没有主键的表进行更新.插入和删除的动作.用xml方式查看edmx ...

  2. javascript简单介绍总结(二)

    JavaScript 函数函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.JavaScript 函数语法函数就是包裹在花括号中的代码块,前面使用了关键词 function:function ...

  3. Selenium with Python 005 - 调用js操作页面元素

    WebDriver提供了execute_script()方法来执行JavaScript方法,格式如 driver.execute_script(script,*args) 执行js一般有两种场景,一是 ...

  4. 四十 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)倒排索引

    倒排索引 倒排索引源于实际应用中需要根据属性的值来查找记录.这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址.由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引 ...

  5. 更新增加一个门店ID字段的值

    MYSQL因为不能查询一张表时同时更新一张表,同时又会有子查询大于等于一条的情况出现. 分两种情况: 1 直接JOIN 得到一张表. 然后导出做筛选 CREATE TABLE TEST SELECT ...

  6. 【scala】可变参数

    Scala允许使用可变的参数列表. 语法 在声明的参数类型后边添加星号(*) 示例 object HelloWorld{ def hello(args:String*): Unit ={ for(ar ...

  7. java svnkit实现svn提交,更新等操作

    官网:https://svnkit.com/ api:https://svnkit.com/javadoc/org/tmatesoft/svn/core/io/SVNRepository.html w ...

  8. JS同源策略和跨域访问

    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的,浏览器只 ...

  9. (四)js数组方法一

    ES5数组方法: Array.prototype.filter()   对数组元素进行过滤 三个参数:元素值,下标,原数组 返回:过滤后符合条件的数组,不会改变原数组 let arr = [2,4,6 ...

  10. 51nod 1089 最长回文子串 V2(Manacher算法)

    回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度. 收起   输入 输入Str(Str的长度 <= 100000) ...