对象

看个例子

<?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. web自动化常用定位和方法总结

    一. driver常用方法 二. 常用定位 三. 元素在页面不可见区域 四. iframe的操作 五. 页面弹出框:加等待时间 六. windows弹出框 七. 鼠标操作 八. 下拉列表 注意:下图中 ...

  2. 教你如何使用node.js制作代理服务器

    var http=require("http"); var url=require("url"); var server=http.createServer(f ...

  3. ARM体系结构总结

    特殊功能寄存器与外设绑定,通用寄存器是与CPU绑定. ARM是RISC架构 常用ARM汇编指令只有二三十条 ARM是低功耗CPU ARM的架构非常适合单片机.嵌入式.尤其是物联网领域:而服务器等高性能 ...

  4. LeetCode OJ:Linked List Cycle II(循环链表II)

    Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note ...

  5. 【数据库】python访问mysql

    import MySQLdb 所有的数据库遵循相同的python database API 需要建立connection对象连接数据库,之后建立cursor对象处理数据. conn = MySQLdb ...

  6. zoj-3963 Heap Partition(贪心+二分+树状数组)

    题目链接: Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence ...

  7. Compiling OpenGL games with the Flash C Compiler (FlasCC)

    Compiling OpenGL games with the Flash C Compiler (FlasCC) In this article I show how to use the Flas ...

  8. (效果三)js实现选项卡切换

    开发了很久的小程序,在接到一个h5移动端页面的时候,很多原生的东西都忘了,虽然说我们随着工作经验的增加,处理业务逻辑的能力在提高,但是基础的东西如果长时间不用,也会逐渐忘记.所以以后会经常总结原生的一 ...

  9. LINUX (centos)设置IP地址,网关,DNS

    首先:备份原始配置文件: [logonmy@logon ~]$ cd /etc/sysconfig/network-scripts/ [logon@logon network-scripts]$ pw ...

  10. 剑指Offer面试题:1.实现单例模式

    一 题目:实现单例模式Singleton 题目:设计一个类,我们只能生产该类的一个实例. 只能生成一个实例的类是实现了Singleton(单例)模式的类型.由于设计模式在面向对象程序设计中起着举足轻重 ...