LAMP安装所需的一些软件包

By 深空, 2010年06月17日 17:27
    httpd

  1. 包名: httpd-2.2.15.tar.gz
  2. 下载地址: http://httpd.apache.org/download.cgi
  3. 包路径: http://labs.renren.com/apache-mirror/httpd/httpd-2.2.15.tar.gz
    mysql

  1. 包名: mysql-5.1.48.tar.gz
  2. http://www.mysql.com/downloads/mysql/
  3. http://mysql.byungsoo.net/Downloads/MySQL-5.1/mysql-5.1.48.tar.gz
    php

  1. 包名: php-5.3.2.tar.gz
  2. http://www.php.net/downloads.php
  3. http://cn2.php.net/get/php-5.3.2.tar.gz/from/cn.php.net/mirror
    libxml2

  1. 包名: libxml2-2.6.30-.tar.gz
  2. http://ftp.gnome.org/pub/GNOME/sources/libxml2
  3. http://ftp.acc.umu.se/pub/GNOME/sources/libxml2/2.6/libxml2-2.6.30.tar.gz
    libxslt

  1. 包名: libxslt-1.1.22.tar.gz
  2. http://ftp.acc.umu.se/pub/GNOME/sources/libxslt/
  3. http://ftp.acc.umu.se/pub/GNOME/sources/libxslt/1.1/libxslt-1.1.22.tar.gz
    curl

  1. 包名: curl-7.20.1.tar.gz
  2. http://curl.haxx.se/download/
  3. http://curl.haxx.se/download/curl-7.20.1.tar.gz
    gd2

  1. 包名: gd-2.0.35.tar.gz
  2. http://www.libgd.org/releases/
  3. http://www.libgd.org/releases/gd-2.0.35.tar.gz
    freetype

  1. 包名: freetype-2.3.12.tar.gz
  2. http://sourceforge.net/projects/freetype/files/
  3. http://sourceforge.net/projects/freetype/files/freetype2/2.3.12/freetype-2.3.12.tar.gz/download
    jpeg

  1. 包名: jpegsrc.v8b.tar.gz
  2. http://ijg.org/files/
  3. http://ijg.org/files/jpegsrc.v8b.tar.gz
    libpng

  1. 包名: libpng-1.4.2.tar.gz
  2. http://www.libpng.org/pub/png/libpng.html
  3. http://download.sourceforge.net/libpng/libpng-1.4.2.tar.gz
    zlib

  1. 包名: gd-2.0.35.tar.gz
  2. http://www.zlib.net/
  3. http://zlib.net/zlib-1.2.5.tar.gz
    cronolog

  1. 包名: cronolog-1.6.2.tar.gz
  2. http://cronolog.org/download/index.html
  3. http://cronolog.org/download/cronolog-1.6.2.tar.gz
    libmcrypt

  1. 包名: libmcrypt-2.5.8.tar.gz
  2. http://sourceforge.net/projects/mcrypt/files/Libmcrypt/
  3. http://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz/download
    oracle

  1. 包名:
    oracle-instantclient11.2-basic-11.2.0.1.0-1.x86_64.zip,
    oracle-instantclient11.2-sqlplus-11.2.0.1.0-1.x86_64.zip,
    oracle-instantclient11.2-sdk-11.2.0.1.0-1.x86_64.zip
  2. http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/linuxx86_64soft.html
  3. http://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz/download
VN:F [1.9.3_1094]
Rating: 8.6/10 (5 votes cast)
VN:F [1.9.3_1094]
Rating: +1 (from 1 vote)

WEB监控体系之设备负载监控

By 深空, 2010年04月11日 19:14

  第一次写和工作密切相关的文章,却无从下手,胡乱写起,纯当总结。

  设备负载监控属于硬件级的基础监控,比设备基础监控粒度要粗一些,属于设备基础监控上一层的硬件监控,适合于数量较大、具有集群特性的硬件综合指标监控。当然,其监控数据来源仍为单机设备基础信息。

  单机基础硬件指标大概包括CPU使用率、内存使用率、磁盘I/O、磁盘空间使用率、网卡出入包量、网卡出入流量、平均负载等。那么各种业务逻辑可能对这些指标都会有所侧重,例如WEB服务器比较侧重CPU、包量、流量,而DB比较侧重磁盘I/O、CPU使用率,CACHE则更关注内存使用率、CPU使用率等。对于数量庞大、类型不一的服务器,不可能关注到这么细致的数据信息,所以必须在几个维度进行汇总以便更好实现服务器管理。

  那么设备负载监控系统的设计目标是什么呢?大概总结有以下几点:
  1、减少管理单元,提高维护效率;
  2、方便查看业务总体负载状况;
  3、尽快发现高负载设备以便及时增加设备缓解业务压力;
  4、减少空闲设备量,提高设备复用率,降低设备成本;
  5、发现负载均衡方面的问题

  要实现以上几个目标,首先需要将服务器分门别类。如WEB、DB、CACHE、业务逻辑等。上面提到,这些设备应该具备集群特性,其大概形式如下:

集群示意图

集群示意图


  如上图所示,除灰色部分外,该集群拥有4台一样的设备,每台设备上均安装有1、2、3三种软件,这样这些设备的正常运行状况应该基本一致。当该集群呈现负载较繁忙的状况的时候,可以比较容易复制1-4号设备以增加一台一样的5号设备来降低业务负载。而当该集群负载较空闲的时候,可以将第4号软件部署于该集群下以充分利用设备性能。

  在该集群负载均衡的状况下,单机的负载状况表现出来的特征,应该就是该集群的负载特征,通过管理集群即可映射到管理单机设备,假设有1000台设备,每个集群50台,那么只需要管理20个集群即可,管理单元明显减少。

  在现实情况下,其实无法达到百分百负载均衡,所以还是需要一些算法计算集群的指标。最基本的算法就是MAX、MIN、AVG了。这三个基本可以处理90%以上情况。我曾经设计过比较复杂的公式支持,后来发现基本上用不上。当然算法越粗暴误差越大。如使用MAX计算CPU使用率,那么假如该集群下某台设备由于特殊原因CPU一直占用较高,那么表现在集群上的CPU使用率也会较高,而实际情况可能这个集群相对空闲。而使用AVG求平均数值,那么一些异常设备将会被淹没不能及时发现,所以这里需要根据业务特性做一些权衡和取舍。当然不建议使用更复杂的算法,因为配置维护成本比较高,而且数值计算结果不直观。

  为了修正个别设备引起集群高负载的问题,引入了高负载设备数的指标。假如该集群负载较高且高负载设备数也高于某个比例(如50%)则认为该负载值准确描述集群压力状况。

  接下来看看实际指标的计算方法。

  首先是负载值的定义。考虑到单机指标太多,业务复杂,所以一律是用百分比来反映负载状况。如10%负载、80%负载、200%负载等。这样单位统一直观。而不需要去考虑具体单位和具体数值。以CPU使用率为例,假设当CPU使用率为80%的时候,负载为100%,那么将80定义为CPU使用率的基准值,当CPU使用率为40%的时候,计算出来的负载为50%,而当CPU使用率为100%时,计算出来的负载为125%。同样其他指标需要定义一些基准值做为负载100%的值。例如百M网卡定义80M为100%负载等。

  这样单机所有基础指标均可以使用百分比表示,CPU使用率、内存使用率、磁盘I/O、磁盘空间使用率、网卡出入包量、网卡出入流量等均换算成负载比例,根据设备所属类型(WEB、DB、CACHE、逻辑等)设计权重结合计算公式得到单机负载值,如:

  单机负载 = AVG(CPU使用率*权重/CPU使用率基准,出流量*权重/出流量基准…);

  实际上单机负载的作用只在于计算高负载设备数。因为这样的计算方式累加到集群中的负载值误差会偏大。为了修正这一问题,引入集群指标负载的概念,即:集群的CPU使用率负载、集群流量负载等,由于同一集群的各项指标较相近,这样将同类型指标进行叠加,减少误差,其公式如下:

  集群CPU使用率负载 = AVG(设备1CPU使用率/CPU使用率基准,设备2CPU使用率/CPU使用率基准,…);

  从业务结构上看,会有如下关系图:

逻辑结构示意图

逻辑结构示意图

  以上为现阶段使用的计算关系图,还有另外一种误差较大的关系图如下:

单机管理关系图

单机管理关系图


  上图设备负载计算主要用于单机负载管理上,实际从单机负载直接计算集群负载的误差会较大,所以一般会采用前一种计算逻辑。不过视图2还能较为直观反映某一集群的负载均衡问题。

  实际上负载监控的作用远远高于其起初设计目标。随着业务的增长,可以看到集群负载也随之增长,虽然有波动,但是通过计算后仍会随着业务增长表现出增长趋势,那么系统就可以根据近一段时间内的负载增长状况,结合业务实际增长状况,预测出未来该集群所要达到的负载值,当超过一个临界值的时候(如80%负载),可以有计划的实行扩容操作(增加设备),而不是等到业务突然呈现高负荷、稳定性降低的时候,才紧急进行设备扩充。

  关于负载预测,我在之前有提到过,我是使用线性回归方法计算的,其中最小二乘法计算公式如下:

最小二乘法公式

最小二乘法公式


  下面代码简单枚举历史10个点来计算该设备负载增长率:

//Y坐标值表示设备历史负载
$y = array(52.09, 52.4, 53.29, 54.22, 55.15, 55.83, 56.89, 56.98, 57.55, 57.8);

//X坐标值表示顺序天数
$x = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

//计算X和Y均值
$ax = array_sum($x)/count($x);
$ay = array_sum($y)/count($y);

//计算斜率公式中的分母(em)和分子(ez)
$em = 0;
$ez = 0;
for ($i = 0; $i < count($x); $i++) {
    //分母求和
    $em += (($x[$i] - $ax) * ($y[$i] - $ay));
    //分子求和
    $ez += pow(($x[$i] - $ax), 2);
}

//斜率0.69
echo $em/$ez;

//第十一个点预测负载值58.34
echo $em/$ez * 10 + $ay - ($em/$ez)*$ax;

  理想状况下,将负载维持到一个稳定的值,使得设备使用率达到最高,且业务稳定正常,是一个长期的调整过程,通过不断的增减设备--增加设备以降低负载,减少设备以提高设备使用率,降低设备成本。这是一个多方面的协调工作,不是一个负载监控系统能解决的,但是负载监控提供基础的数据支持,可大大提高业务稳定性,减少突发故障,从而提高业务可用性。这里基本需要一些辅助功能的支持:
  1、通过每日高、低负载设备数累计季度总高、低负载设备数来考核运维人员,以便及时处理高、低负载设备,将集群负载维持在一个相对稳定的范围,并消除明显的负载不均衡状况;
  2、每日处理重点业务高负载设备,或者负载异常设备,提高业务稳定性。通常负载异常往往能反应软件故障,如CPU使用率一直100%而流量非常低,则可能是软件BUG导致,及时推动开发人员处理软件BUG或者优化软件以提高设备使用率和增加业务可用性;
  3、定时、有计划的(如一个月一次)对高负载集群进行设备扩充,能大大降低临时扩充设备的维护成本,并减少临时资源池设备量以降低设备成本;
  4、定时对低负载集群进行合并、下线,减少集群数从而减少管理单元,并增加设备利用率以降低设备成本;
  5、系统建设初期还会涉及到覆盖率问题,及时分享业务的负载监控覆盖率,推动业务运维接入,以便能实现100%覆盖,以提高监控能力。

  那么,在系统建设过程中还会碰到哪些问题呢?可能基础数据准确性是个比较重要的问题。由于单机设备硬件基础指标在一天内波动可能会比较大,所以需要对一天所采集到的基础数据进行处理,如消峰、去毛刺,将一些明显异常点去除,取一个较高点做为采集结果数据,以免得到一些高得恐怖的负载值。负载监控在实时性要求上并没有特别的高,对于长期优化目标来看,只需要按天粒度即可,当然由于其计算的合理性,逐渐提高其监控及时性,如按小时监控粒度,以便能更及时的了解到业务运行状况,这种情况一般用在业务放量、新业务上线、设备扩充后的负载实时监控上,以便作出更快的反应。

  另外在集群的划分、归属、分类、合并、共享上,也就是基础配置、关系数据上需要比较细致的维护,目标是做到尽可能的标准化,各个集群既要功能单一独立,在横向上具有强的可扩充性(图1横向),又要能够提供公用以提高设备复用率,如多个集群的合并(图1纵向)。这个涉及到各个业务逻辑的设计,推动业务逻辑按照这种方向进行部署,这样在自动扩容上能达到更好的效果。当集群负载达到一定的数值,会自动调度设备缓冲池里的设备,根据已有的集群内设备的软件配置,自动初始化并接入业务运营,以达到设备自动调度扩充的能力。

  负载监控作为一个长期性和及时性兼顾的监控系统,不仅在提高业务长期稳定性上发挥重要作用,更在预算、成本优化上提供了非常有力的数据支持,而且在未来自动调度扩容的可行性上给出了明朗的答案,是一个衔接业务监控和基础硬件监控的重要基础监控系统。

(待续……)

VN:F [1.9.3_1094]
Rating: 7.8/10 (16 votes cast)
VN:F [1.9.3_1094]
Rating: +5 (from 11 votes)

深圳腾讯互联网运营部招聘运营开发工程师

By 深空, 2010年03月05日 16:45

工作职责:

1. 负责互联网海量用户社区的运营支持系统的建设和开发工作;
2. 参与系统的需求分析、设计、编码等开发工作;
3. 负责相关系统的运营和维护工作,保证系统稳定可靠运行。

工作要求:
1. 计算机相关专业本科以上学历,3年以上开发工作经验;
2. 精通PHP开发,具有大型LAMP系统设计和开发经验;
3. 熟悉数据库,精通SQL和数据结构,具有MySQL或者oracle开发经验为佳;
4. 精通HTML/XHTML、CSS、Javascript等web开发技能;
5. 了解使用linux基本操作命令,熟悉Shell脚本的编写;
6. 同时具有C/C++、CGI、XML、AJAX开发经验为佳;
7. 工作有激情,成就感强烈,热爱开发事业;
8. 学习能力强,具有良好的团队合作能力。

有兴趣的联系我 shenkong#qq.com

VN:F [1.9.3_1094]
Rating: 8.1/10 (12 votes cast)
VN:F [1.9.3_1094]
Rating: +1 (from 3 votes)

简单的PHP日历算法

By 深空, 2009年12月28日 15:22

  看看有没有比我更优的,HOHO。

/**
 * 日历
 *
 * Copyright(c) 2007 by 陈毅鑫(深空). All rights reserved
 * To contact the author write to {@link mailto:shenkong@php.net}
 * @author 陈毅鑫(深空)
 */
if (function_exists('date_default_timezone_set')) {
    date_default_timezone_set('Asia/Chongqing');
}
$date = isset($_GET['date']) ? $_GET['date'] : date('Y-m-d');
$date = getdate(strtotime($date));
$end = getdate(mktime(0, 0, 0, $date['mon'] + 1, 1, $date['year']) - 1);
$start = getdate(mktime(0, 0, 0, $date['mon'], 1, $date['year']));
$pre = date('Y-m-d', $start[0] - 1);
$next = date('Y-m-d', $end[0] + 86400);
$html = '<table border="1">';
$html .= '<tr>';
$html .= '<td><a href="' . $PHP_SELF . '?date=' . $pre . '">-</a></td>';
$html .= '<td colspan="5">' . $date['year'] . ';' . $date['month'] . '</td>';
$html .= '<td><a href="' . $PHP_SELF . '?date=' . $next . '">+</a></td>';
$html .= '</tr>';
$arr_tpl = array(0 => '', 1 => '', 2 => '', 3 => '', 4 => '', 5 => '', 6 => '');
$date_arr = array();
$j = 0;
for ($i = 0; $i < $end['mday']; $i++) {
    if (!isset($date_arr[$j])) {
        $date_arr[$j] = $arr_tpl;
    }
    $date_arr[$j][($i+$start['wday'])%7] = $i+1;
    if ($date_arr[$j][6]) {
        $j++;
    }
}
foreach ($date_arr as $value) {
    $html .= '<tr>';
    foreach ($value as $v) {
        if ($v) {
            if ($v == $date['mday']) {
                $html .= '<td><b>' . $v . '</b></td>';
            } else {
                $html .= '<td>' . $v . '</td>';
            }
        } else {
            $html .= '<td>&nbsp;</td>';
        }
    }
    $html .= '</tr>';
}
$html .= '</table>';
echo $html;
VN:F [1.9.3_1094]
Rating: 7.6/10 (27 votes cast)
VN:F [1.9.3_1094]
Rating: +13 (from 25 votes)

《Head First 设计模式》代码之PHP版

By 深空, 2009年12月28日 09:49

  《Head First 设计模式》是本不错的讲解设计模式的书,不像F4写的那么枯燥,应该算是比较容易理解的好书。书中的例子都比较浅显易懂,不过由于是外国佬写的,所以例子的习惯不是很附合中国特色,可能偶尔看起来有些别扭,还有语言习惯也不是中国风。当然��看过这本书之后,你才能深刻理解设计模式到底能为你解决哪些问题,不能为你解决哪些问题(比如不能代替你的编码)。
  我将书中部分代码改成PHP,看下代码再配合概念应该是比较容易理解了。
  策略模式

<?php
/**
 * 策略模式
 * 定义了算法族,分别封装起来,让它们之间可以互相替换,
 * 此模式让算法的变化独立于使用算法的客户。
 */
//飞行行为接口
interface FlyBehavior {
    public function fly();
}
//呱呱叫行为接口
interface QuackBehavior {
    public function quack();
}
//翅膀飞行
class FlyWithWings implements FlyBehavior {
    public function fly() {
        echo "I'm flying!!\n";
    }
}
//不会飞
class FlyNoWay implements FlyBehavior {
    public function fly() {
        echo "I can't fly!\n";
    }
}
class FlyRocketPowered implements FlyBehavior {
    public function fly() {
        echo "I'm flying with a rocket!\n";
    }
}
class Qquack implements QuackBehavior {
    public function quack() {
        echo "Quack\n";
    }
}
class Squeak implements QuackBehavior {
    public function quack() {
        echo "Squeak\n";
    }
}
class MuteQuack implements QuackBehavior {
    public function quack() {
        echo "<< Silence >>\n";
    }
}
abstract class Duck {
    protected $quack_obj;
    protected $fly_obj;
    public abstract function display();

    public function performQuack() {
        $this->quack_obj->quack();
    }
    public function performFly() {
        $this->fly_obj->fly();
    }
    public function swim() {
        echo "All ducks float, even decoys!\n";
    }
    public function setFlyBehavior(FlyBehavior $fb) {
        $this->fly_obj = $fb;
    }
    public function setQuackBehavior(QuackBehavior $qb) {
        $this->quack_obj = $qb;
    }
}

class ModelDuck extends Duck {
    public function __construct() {
        $this->fly_obj = new FlyNoWay();
        $this->quack_obj = new MuteQuack();
    }
    public function display() {
        echo "I'm a model duck!\n";
    }
}

$model = new ModelDuck();
$model->performFly();
$model->performQuack();
//提供新的能力
$model->setFlyBehavior(new FlyRocketPowered());
$model->setQuackBehavior(new Squeak());
$model->performFly();
$model->performQuack();

?>

  单件模式

<?php
/**
 * 单件模式
 * 确保一个类只有一个实例,并提供一个全局访问点。
 */
class MyClass {
    private static $uniqueInstance;
    private function __construct() {

    }
    public static function getInstance() {
        if (self::$uniqueInstance == null) {
            self::$uniqueInstance = new MyClass();
        }
        return self::$uniqueInstance;
    }
}
$myClass = MyClass::getInstance();
var_dump($myClass);
$myClass = MyClass::getInstance();
var_dump($myClass);
?>

  工厂方法模式

<?php
abstract class PizzaStore {
    public function orderPizza($type) {
        $pizza = $this->createPizza($type);

        $pizza->prepare();
        $pizza->bake();
        $pizza->cut();
        $pizza->box();
        return $pizza;
    }

    public abstract function createPizza($type);
}
class NYPizzaStore extends PizzaStore {
    public function createPizza($type) {
        if ($type == "cheese") {
            return new NYStyleCheesePizza();
        } elseif ($type == "veggie") {
            return new NYStyleVeggiePizza();
        } elseif ($type == "clam") {
            return new NYStyleClamPizza();
        } elseif ($type == "papperoni") {
            return new NYStylePapperoniPizza();
        } else {
            return null;

        }
    }
}
class ChicagoPizzaStore extends PizzaStore {
    public function createPizza($type) {
        if ($type == "cheese") {
            return new ChicagoStyleCheesePizza();
        } elseif ($type == "veggie") {
            return new ChicagoStyleVeggiePizza();
        } elseif ($type == "clam") {
            return new ChicagoStyleClamPizza();
        } elseif ($type == "papperoni") {
            return new ChicagoStylePapperoniPizza();
        } else {
            return null;
        }
    }
}
abstract class Pizza {
    public $name;
    public $dough;
    public $sauce;
    public $toppings = array();

    public function prepare() {
        echo "Preparing " . $this->name . "\n";
        echo "Yossing dough...\n";
        echo "Adding sauce...\n";
        echo "Adding toppings: \n";
        for ($i = 0; $i < count($this->toppings); $i++) {
            echo "    " . $this->toppings[$i] . "\n";
        }
    }

    public function bake() {
        echo "Bake for 25 minutes at 350\n";
    }

    public function cut() {
        echo "Cutting the pizza into diagonal slices\n";
    }

    public function box() {
        echo "Place pizza in official PizzaStore box\n";
    }

    public function getName() {
        return $this->name;
    }
}

class NYStyleCheesePizza extends Pizza {
    public function __construct() {
        $this->name = "NY Style Sauce and cheese Pizza";
        $this->dough = "Thin Crust Dough";
        $this->sauce = "Marinara Sauce";

        $this->toppings[] = "Grated Reggiano Cheese";
    }
}

class NYStyleVeggiePizza extends Pizza {
    public function __construct() {
        $this->name = "NY Style Sauce and veggie Pizza";
        $this->dough = "Thin Crust Dough";
        $this->sauce = "Marinara Sauce";

        $this->toppings[] = "Grated Reggiano veggie";
    }
}
class NYStyleClamPizza extends Pizza {
    public function __construct() {
        $this->name = "NY Style Sauce and clam Pizza";
        $this->dough = "Thin Crust Dough";
        $this->sauce = "Marinara Sauce";

        $this->toppings[] = "Grated Reggiano clam";
    }
}
class NYStylePapperoniPizza extends Pizza {
    public function __construct() {
        $this->name = "NY Style Sauce and papperoni Pizza";
        $this->dough = "Thin Crust Dough";
        $this->sauce = "Marinara Sauce";

        $this->toppings[] = "Grated Reggiano papperoni";
    }
}

class ChicagoStyleCheesePizza extends Pizza {
    public function __construct() {
        $this->name = "Chicago Style Deep Dish Cheese Pizza";
        $this->dough = "Extra Thick Crust Dough";
        $this->sauce = "Plum Tomato Sauce";

        $this->toppings[] = "Shredded Mozzarella Cheese";
    }

    public function cut() {
        echo "Cutting the pizza into square slices\n";
    }
}

$myStore = new NYPizzaStore();
$chicagoStore = new ChicagoPizzaStore();
$pizza = $myStore->orderPizza("cheese");
echo "Ethan ordered a " . $pizza->getName() . "\n";

$pizza = $chicagoStore->orderPizza("cheese");
echo "Ethan ordered a " . $pizza->getName() . "\n";

?>

  工厂模式

<?php
abstract class PizzaStore {
    public function orderPizza($type) {
        $pizza = $this->createPizza($type);

        $pizza->prepare();
        $pizza->bake();
        $pizza->cut();
        $pizza->box();
        return $pizza;
    }

    public abstract function createPizza($type);
}
class NYPizzaStore extends PizzaStore {
    public function createPizza($type) {
        $pizza = null;
        $ingredientFactory = new NYPizzaIngredientFactory();
        if ($type == "cheese") {
            $pizza = new CheesePizza($ingredientFactory);
            $pizza->setName('New York Style Cheese Pizza');
        } elseif ($type == "veggie") {
            $pizza = new VeggiePizza($ingredientFactory);
            $pizza->setName('New York Style Veggie Pizza');
        } elseif ($type == "clam") {
            $pizza = new ClamPizza($ingredientFactory);
            $pizza->setName('New York Style Clam Pizza');
        } elseif ($type == "papperoni") {
            $pizza = new PapperoniPizza($ingredientFactory);
            $pizza->setName('New York Style Papperoni Pizza');
        }
        return $pizza;
    }
}
class ChicagoPizzaStore extends PizzaStore {
    public function createPizza($type) {
        if ($type == "cheese") {
            return new ChicagoStyleCheesePizza();
        } elseif ($type == "veggie") {
            return new ChicagoStyleVeggiePizza();
        } elseif ($type == "clam") {
            return new ChicagoStyleClamPizza();
        } elseif ($type == "papperoni") {
            return new ChicagoStylePapperoniPizza();
        } else {
            return null;
        }
    }
}
interface PizzaIngredientFactory {
    public function createDough();
    public function createSauce();
    public function createCheese();
    public function createVeggies();
    public function createPepperoni();
    public function createClam();
}
class NYPizzaIngredientFactory implements PizzaIngredientFactory {
    public function createDough() {
        return new ThinCrustDough();
    }
    public function createSauce() {
        return new MarinaraSauce();
    }
    public function createCheese() {
        return new ReggianoCheese();
    }
    public function createVeggies() {
        $veggies = array(
        new Garlic(),
        new Onion(),
        new Mushroom(),
        new RedPepper(),
        );
        return $veggies;
    }
    public function createPepperoni() {
        return new SlicedPepperoni();
    }
    public function createClam() {
        return new FreshClams();
    }
}
class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
    public function createDough() {
        return new ThickCrustDough();
    }
    public function createSauce() {
        return new PlumTomatoSauce();
    }
    public function createCheese() {
        return new Mozzarella();
    }
    public function createVeggies() {
        $veggies = array(
        new BlackOlives(),
        new Spinach(),
        new EggPlant(),
        );
        return $veggies;
    }
    public function createPepperoni() {
        return new SlicedPepperoni();
    }
    public function createClam() {
        return new FrozenClams();
    }
}
abstract class Pizza {
    public $name;
    public $dough;
    public $sauce;
    public $veggies = array();
    public $cheese;
    public $pepperoni;
    public $clam;

    public abstract function prepare();

    public function bake() {
        echo "Bake for 25 minutes at 350\n";
    }

    public function cut() {
        echo "Cutting the pizza into diagonal slices\n";
    }

    public function box() {
        echo "Place pizza in official PizzaStore box\n";
    }

    public function getName() {
        return $this->name;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function __toString() {

    }
}

class CheesePizza extends Pizza {
    public $ingredientFactory;

    public function __construct(PizzaIngredientFactory $ingredientFactory) {
        $this->ingredientFactory = $ingredientFactory;
    }

    public function prepare() {
        echo "Preparing " . $this->name . "\n";
        $this->dough = $this->ingredientFactory->createDough();
        $this->sauce = $this->ingredientFactory->createSauce();
        $this->cheese = $this->ingredientFactory->createCheese();
    }
}

class ClamPizza extends Pizza {
    public $ingredientFactory;

    public function __construct(PizzaIngredientFactory $ingredientFactory) {
        $this->ingredientFactory = $ingredientFactory;
    }

    public function prepare() {
        echo "Preparing " . $this->name . "\n";
        $this->dough = $this->ingredientFactory->createDough();
        $this->sauce = $this->ingredientFactory->createSauce();
        $this->cheese = $this->ingredientFactory->createCheese();
        $clam = $this->ingredientFactory->createClam();
    }
}

$nyPizzaStore = new NYPizzaStore();
$nyPizzaStore->orderPizza('cheese');
?>

  观察者模式

<?php
/**
 * 观察者模式
 * 定义了对象之间的一对多依赖,当一个对象改变状态时,
 * 它的所有依赖者都会收到通知并自动更新。
 */
interface Subject {
    public function registerObserver(Observer $o);
    public function removeObserver(Observer $o);
    public function notifyObservers();
}
interface Observer {
    public function update($temperature, $humidity, $pressure);
}
interface DisplayElement {
    public function display();
}
class WeatherData implements Subject {
    private $observers = array();
    private $temperature;
    private $humidity;
    private $pressure;
    public function __construct() {
        $this->observers = array();
    }
    public function registerObserver(Observer $o) {
        $this->observers[] = $o;
    }
    public function removeObserver(Observer $o) {
        if (($key = array_search($o, $this->observers)) !== false) {
            unset($this->observers[$key]);
        }
    }
    public function notifyObservers() {
        foreach ($this->observers as $observer) {
            $observer->update($this->temperature, $this->humidity, $this->pressure);
        }
    }
    public function measurementsChanged() {
        $this->notifyObservers();
    }
    public function setMeasurements($temperature, $humidity, $pressure) {
        $this->temperature = $temperature;
        $this->humidity = $humidity;
        $this->pressure = $pressure;
        $this->measurementsChanged();
    }
}
class CurrentConditionsDisplay implements Observer, DisplayElement {
    private $temperature;
    private $humidity;
    private $weatherData;
    public function __construct(Subject $weatherData) {
        $this->weatherData = $weatherData;
        $weatherData->registerObserver($this);
    }
    public function update($temperature, $humidity, $pressure) {
        $this->temperature = $temperature;
        $this->humidity = $humidity;
        $this->display();
    }
    public function display() {
        echo "温度:" . $this->temperature . "; 湿度:" . $this->humidity . "%\n";
    }
}
class StatistionsDisplay implements Observer, DisplayElement {
    private $temperature;
    private $humidity;
    private $pressure;
    private $weatherData;
    public function __construct(Subject $weatherData) {
        $this->weatherData = $weatherData;
        $weatherData->registerObserver($this);
    }
    public function update($temperature, $humidity, $pressure) {
        $this->temperature = $temperature;
        $this->humidity = $humidity;
        $this->pressure = $pressure;
        $this->display();
    }
    public function display() {
        echo "温度:" . $this->temperature . "; 湿度:" . $this->humidity . "%; 气压:" . $this->pressure . "\n";
    }
}
$weatherData = new WeatherData();
$currentDisplay = new CurrentConditionsDisplay($weatherData);
$statistionDisplay = new StatistionsDisplay($weatherData);
$weatherData->setMeasurements(10, 20, 30);
$weatherData->removeObserver($currentDisplay);
$weatherData->setMeasurements(30, 40, 50);
?>

  命令模式

<?php

class Light {
    public function __construct() {

    }

    public function on() {
        echo "Light On\n";
    }

    public function off() {
        echo "Light Off\n";
    }
}

interface Command {
    public function execute();
}

class LightOnCommand implements Command {
    public $light;

    public function __construct(Light $light) {
        $this->light = $light;
    }

    public function execute() {
        $this->light->on();
    }
}

class SimpleRemoteControl {
    public $slot;

    public function __construct() {

    }

    public function setCommand(Command $command) {
        $this->slot = $command;
    }

    public function buttonWasPressed() {
        $this->slot->execute();
    }
}

class RemoteControlTest {
    public static function main() {
        $remote = new SimpleRemoteControl();
        $light = new Light();
        $lightOn = new LightOnCommand($light);
        $remote->setCommand($lightOn);
        $remote->buttonWasPressed();
    }
}

RemoteControlTest::main();

?>

  装饰者模式

<?php
/**
 * 装饰着模式
 * 动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
 */
abstract class Beverage {
    public $description = "Unknown Beverage";

    public function getDescription() {
        return $this->description;
    }

    public abstract function cost();
}

abstract class CondimentDecorator extends Beverage {
    //JAVA代码里这里是个抽象类,PHP不允许这么做
    public function getDescription() {
        return $this->description;
    }
}

class Espresso extends Beverage {
    public function __construct() {
        $this->description = "Espresso";
    }

    public function cost() {
        return 1.99;
    }
}

class HouseBlend extends Beverage {
    public function __construct() {
        $this->description = "HouseBlend";
    }

    public function cost() {
        return .89;
    }
}

class DarkRoast extends Beverage {
    public function __construct() {
        $this->description = "DarkRoast";
    }

    public function cost() {
        return .99;
    }
}

class Mocha extends CondimentDecorator {
    public $beverage;

    public function __construct(Beverage $beverage) {
        $this->beverage = $beverage;
    }
    public function getDescription() {
        return $this->beverage->getDescription() . ", Mocha";
    }
    public function cost() {
        return .20 + $this->beverage->cost();
    }
}

class Whip extends CondimentDecorator {
    public $beverage;

    public function __construct(Beverage $beverage) {
        $this->beverage = $beverage;
    }
    public function getDescription() {
        return $this->beverage->getDescription() . ", Whip";
    }
    public function cost() {
        return .10 + $this->beverage->cost();
    }
}

class Soy extends CondimentDecorator {
    public $beverage;

    public function __construct(Beverage $beverage) {
        $this->beverage = $beverage;
    }
    public function getDescription() {
        return $this->beverage->getDescription() . ", Soy";
    }
    public function cost() {
        return .15 + $this->beverage->cost();
    }
}

$beverage = new Espresso();
echo $beverage->getDescription() . "\n";
$beverage2 = new DarkRoast();
$beverage2 = new Mocha($beverage2);
$beverage2 = new Mocha($beverage2);
$beverage2 = new Whip($beverage2);
echo $beverage2->getDescription() . " $" . $beverage2->cost() . "\n";

$beverage3 = new HouseBlend();
$beverage3 = new Soy($beverage3);
$beverage3 = new Mocha($beverage3);
$beverage3 = new Whip($beverage3);
echo $beverage3->getDescription() . " $" . $beverage3->cost() . "\n";
?>

  状态模式

<?php

class GumballMachine {
    const SOLD_OUT = 0;
    const NO_QUARTER = 1;
    const HAS_QUARTER = 2;
    const SOLD = 3;

    public $state = self::SOLD_OUT;
    public $count = 0;

    public function __construct($count) {
        $this->count = $count;
        if ($count > 0) {
            $this->state = self::NO_QUARTER;
        }
    }

    public function insertQuarter() {
        if ($this->state == self::HAS_QUARTER) {
            echo "You can't insert another quarter!\n";
        } else if ($this->state == self::NO_QUARTER) {
            $this->state = self::HAS_QUARTER;
            echo "You inserted a quarter!\n";
        } else if ($this->state == self::SOLD_OUT) {
            echo "You can't insert a quarter, the machine is sold out!\n";
        } else if ($this->state == self::SOLD) {
            echo "Please wait, we're already giving you a gumball!\n";
        }
    }
}

$obj = new GumballMachine(0);
print_r($obj)

?>
VN:F [1.9.3_1094]
Rating: 9.7/10 (9 votes cast)
VN:F [1.9.3_1094]
Rating: +6 (from 6 votes)

京ICP备05002071号 ©2003-2010 深空