php的设计模式

题外话:前几天到一家公司面试php职位,来面试我的是一位java工程师,囧。随后他随便问了几个php和java共有的名词,要我解释。当时我就渣了。其中一个就是让我描述设计模式都有哪些。虽然我很久之前隐约学习过,奈何时间久远,脑子里早就自动缓存失效。最近整理印象笔记,把这个问题在cnblogs上简单记录一下。

首先,推荐一本书《设计模式》,本人已在网上找到电子版资料,还没开始阅读,欢迎阅读过的小伙伴前来发表阅读感想!

网上很多资料都是从五个设计模式做的介绍,我的笔记同样如此。包括‘工厂模式’、‘单例模式/单元素模式’、‘观察者模式’、‘命令链模式‘、‘策略模式’ ,下面我们开始一一介绍。

一、工厂模式

概念理解:工厂模式是一种具有创建对象的某种方法的类。我们可以使用工厂类直接创建对象,new的过程由工厂完成。如果我们需要修改所创建的对象类型,只需要更改工厂即可,调用工厂的所有代码都会自动更改。

优点:工厂模式的优点在于创建对象。就是把创建对象的过程封装起来,每次调用工厂的某个方法就自动创建了对象。

设计思想:根据不同参数生成不同类实例。

工厂模式划分:根据抽象程度的不同,可以分为 简单工厂模式、工厂方法模式和抽象工厂模式。下面看一下demo.

*简单工厂模式

<?php
/**
 * 简单工厂模式又叫静态工厂方法模式,理解为可以通过一个静态方法创建对象
 * */

interface animal{
    function eat();
}
class herbivore implements animal{
    function eat(){
        echo "吃草<br>";
    }
}
class carnivore implements animal{
    function eat(){
        echo "吃肉<br>";
    }
}
class omnivores implements animal{
    function eat(){
        echo "杂食<br>";
    }
}

class Demo{
    static function createHerbivore(){
        return new herbivore;
    }
    static function createCarnivore(){
        return new carnivore;
    }
    static function createOmnivores(){
        return new omnivores;
    }
}
$herbivore = Demo::createHerbivore();
$herbivore->eat();
$carnivore = Demo::createCarnivore();
$carnivore->eat();
$omnivores = Demo::createOmnivores();
$omnivores->eat();

*工厂方法模式

<?php
/**
 * 工厂模式 定义一个创建对象的接口,让子类决定哪个类实例化,解决简单工厂模式中封闭开发原则
 * */

interface animal{
    function eat();
}
class herbivore implements animal{
    function eat(){
        echo "吃草<br>";
    }
}
class carnivore implements animal{
    function eat(){
        echo "吃肉<br>";
    }
}
class omnivores implements animal{
    function eat(){
        echo "杂食<br>";
    }
}
//将对象的创建抽象成一个接口
interface createAnimal{
    function create();
}
class FactoryHerbivore implements createAnimal{
    function create(){
        return new herbivore;
    }
}
class FactoryCarnivore implements createAnimal{
    function create(){
        return new carnivore;
    }
}
class FactoryOmnivores implements createAnimal{
    function create(){
        return new omnivores;
    }
}
class Demo{
    function test(){
        $Factory = new FactoryHerbivore();
        $herbivore = $Factory->create();
        $herbivore->eat();

        $Factory = new FactoryCarnivore();
        $carnivore = $Factory->create();
        $carnivore->eat();

        $Factory = new FactoryOmnivores();
        $omnivores = $Factory->create();
        $omnivores->eat();
    }
}

$demo = new Demo();
$demo->test();

*抽象工厂方法

<?php
/**
 * 抽象工厂  提供一个创建一系列相关或相互依赖对象的接口
 * 与工厂方法的区别,这里定义了一系列接口,工厂方法只有一个
 *
 * */

interface animal{
    function eat();
}
class yesHerbivore implements animal{
    function eat(){
        echo "吃草<br>";
    }
}
class noHerbivore implements animal{
    function eat(){
        echo "不吃草<br>";
    }
}
class yesCarnivore implements animal{
    function eat(){
        echo "吃肉<br>";
    }
}
class noCarnivore implements animal{
    function eat(){
        echo "不吃肉<br>";
    }
}
class yesOmnivores implements animal{
    function eat(){
        echo "杂食<br>";
    }
}
class noOmnivores implements animal{
    function eat(){
        echo "不杂食<br>";
    }
}
//本质区别在这里,将对象的创建抽象成一个接口
interface createAnimal{
    function createYes();
    function createNo();
}
class FactoryHerbivore implements createAnimal{
    function createYes(){
        return new yesHerbivore();
    }
    function createNo(){
        return new noHerbivore();
    }
}
class FactoryCarnivore implements createAnimal{
    function createYes(){
        return new yesCarnivore();
    }
    function createNo(){
        return new noCarnivore();
    }
}
class FactoryOmnivores implements createAnimal{
    function createYes(){
        return new yesOmnivores();
    }
    function createNo(){
        return new noOmnivores();
    }
}
class Demo{
    function test(){
        $Factory = new FactoryHerbivore();
        $herbivore = $Factory->createYes();
        $herbivore->eat();

        $herbivore = $Factory->createNo();
        $herbivore->eat();

        $Factory = new FactoryCarnivore();
        $carnivore = $Factory->createYes();
        $carnivore->eat();

        $carnivore = $Factory->createNo();
        $carnivore->eat();

        $Factory = new FactoryOmnivores();
        $omnivores = $Factory->createYes();
        $omnivores->eat();

        $omnivores = $Factory->createNo();
        $omnivores->eat();
    }
}

$demo = new Demo();
$demo->test();

啊咧,为什么我觉得工厂方法模式和抽象工厂方法模式一样呢。。。

适用范围:

简单工厂模式:工厂类负责创建的对象较少,客户只知道传入工厂类的参数,对于如何创建对象不关心。

工厂方法模式:当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时,当类将创建对象的职责委托给多个帮助子类中得某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候,可以使用工厂方法模式。

抽象工厂模式:一个系统不应当依赖于产品类实例何如被创建,组合和表达的细节,这对于所有形态的工厂模式都是重要的。这个系统有多于一个的产品族,而系统只消费其 中某一产品族。同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。系统提供一个产品类的库,所有的产品以同样的接口出现,从 而使客户端不依赖于实现。

无论是简单工厂模式、工厂模式还是抽象工厂模式,它们本质上都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。究竟用哪种设计模式更适合,这要根据具体的业务需求来决定。

再简单一些理解一下,在Thinkphp框架中的Db.class.php就是工厂类,可以操作mysql,oracle等各数据库,以中间层的姿态,屏蔽掉具体的实现,让程序员不改动原来的查询代码。

总之,工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。

推荐阅读:

php设计模式总结-工厂模式

PHP简单工厂模式、工厂方法模式和抽象工厂模式比较

理解PHP的工厂模式Factory Pattern

二、单例/单元素模式

概念理解:单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。我们最常见的应该就是数据库的操作,我们只需要实例化一次,就不需要每次都去new,这样极大的降低了资源的消耗。

其他情况,比如线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序等也都被设计成单例。

单例的特点:只有一个实例,必须自行创建,必须给其他对象提供这一实例。

使用优点:比如在大量数据库操作的场景下,使用单例模式避免频繁大量的new操作,节约了大量的内存和系统的资源。

单例模式的划分:懒汉式单例、饿汉式单例、登记式单例。

<?php 

    class Mysql{
        //该属性用来保存实例
        private static $conn;
        //构造函数为private,防止创建对象
        private function __construct(){
            $this->conn = mysql_connect(‘localhost‘,‘root‘,‘‘);
        }
        //创建一个用来实例化对象的方法
        public static function getInstance(){
            if(!(self::$conn instanceof self)){
                self::$conn = new self;
            }
            return self::$conn;
        }
        //防止对象被复制
        public function __clone(){
            trigger_error(‘Clone is not allowed !‘);
        }

    }
    //只能这样取得实例,不能new 和 clone
    $mysql = Mysql::getInstance();

推荐阅读:

单例模式中的懒汉模式和恶汉模式的区别 标签: 实例对象

php单例模式实现对象只被创建一次

单例模式之懒汉模式&恶汉模式

PHP设计模式-单例模式

php设计模式总结-单件模式

三、观察者模式

理解:观察者和主题(被观察者)都是用接口。观察者利用主题的接口向主题注册,主题利用观察者的接口通知观察者。观察者和主题之间的关系并非通过继承产生,而是在运行时利用组合的方式产生。

下面我们通过代码来了解观察者模式的具体实现。

 //抽象主题
abstract class Subject{
    private $observers = array();//观察者队列
    public function Attach(Observer $observer)
    {    //观察者对象向主题注册
        array_push($this->observers, $observer);
    }
    public function Detach(Observer $observer)
    {    //观察者对象从主题注销 遍历查找
        foreach ($this->observers as $k=>$v)
        {
            if($v==$observer)
            {
                unset($this->observers[$k]);
            }
        }
    }
    function Notify(){
        //主题利用观察者的接口通知观察者 以遍历的方式
        foreach ($this->observers as $v)
        {
            $v->Update();
        }
    }
}

//抽象观察者
abstract class Observer{
    public abstract function Update();//更新操作
}

//具体主题
class concreteSubject extends Subject
{
    public $subject_state;
}

//具体观察者
class ConcreteObserver extends Observer
{
    private $name;
    private $observerState;
    public $subject;

    public function __construct(ConcreteObserver $_sub,$_name)
    {
        $this->subject = $_sub;
        $this->name = $_name;
    }
    public function Update()
    {
        $this->observerState = $this->subject->subject_state;
        echo "观察者".$this->name."的新状态是:".$this->observerState."<br/>";
    }
}
*实现代码* 

$_s = new concreteSubject();//具体主题对象

$testA = new ConcreteObserver($_s, "小A");//具体观察者对象
$testB = new ConcreteObserver($_s, "小B");//具体观察者对象

$_s->Attach($testA);//将观察者对象通过主题对象注册
$_s->Attach($testB);

$_s->subject_state ="状态修改通知";

$_s->Notify();//通知发送

由上我们总结如下:

抽象主题:注册观察者对象,并定义了通知的接口规则

抽象观察者:定义了接到通知后所做的操作接口规则

具体主题:实现抽象主题的接口,接到状态改变则通知观察者

具体观察者:实现具体方法

观察者模式的使用场景:

一个抽象模型有两方面,一方面依赖于另一方面,当对一个对象的改变需要同时改变其他对象,而不需要知道具体有多少对象带改变,松耦合。

缺点:有可能会引起意外的更新。

推荐阅读:

PHP设计模式——观察者模式

PHP设计模式之观察者模式

PHP设计模式之观察者模式(Observer)详细介绍和代码实例

PHP 设计模式之观察者模式

php模式设计之观察者模式

php面向对象设计模式 之 观察者模式

四、命令链模式

概念:命令链模式以松散耦合主题为基础,发送消息、命令和请求,或通过一组处理程序发送任意内容,每个处理程序都会自行判断自己能否处理请求,如果可以,该请求被处理,进程停止。您可以为系统添加或移除处理程序而不影响其他处理程序。

使用场景:可以使用在用户登录注册时处理不同角色用户的业务逻辑与变量值。

如下代码:


interface ICommand
{
    function onCommand($name,$args);
}

class UserCommand implements ICommand
{
    public function onCommand($name,$args)
    {
        if($name !=‘addUser‘) return false;
        echo "UserCommand handling ‘addUser‘ <br>";
        return true;
    }
}

class MailCommand implements ICommand
{
    public function onCommand($name,$args)
    {
        if($name !=‘mail‘) return false;
        echo "UserCommand handling ‘mail‘ <br>";
        return true;
    }
}

class CommandChain
{
    private $_commands = array();
    public function addCommand($cmd){
        $this->_commands[] = $cmd;
    }
    public function runCommand($name,$args){
        foreach ($this->_commands as $cmd){
            if($cmd->onCommand($name,$args))
                return;
        }
    }
}

$test = new CommandChain();
$test->addCommand(new UserCommand());
$test->addCommand(new MailCommand());
$test->runCommand(‘addUser‘, null);
$test->runCommand(‘mail‘, null);

推荐阅读:

php设计模式之命令链模式

PHP设计模式漫谈之命令模式

五种常见的 PHP 设计模式

php设计模式之命令链模式

五、策略模式

概念:策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,此模式让算法的变化独立于使用算法的客户,从而让程序更灵活,具有更好的扩展性和维护性。

设计原则:

找出应用中可能需要变化之处,把它们独立出来,不要和不需要的代码混在一起。针对接口编程,不针对实现编程。多用组合,少用继承。

下面看demo

abstract class Person{
    abstract function show();
}

class minority extends Person
{
    public function show(){
        echo "未成年,二折优惠<br>";
    }
}

class adult extends Person
{
    public function show(){
        echo "成年,五折优惠<br>";
    }
}

class elder extends Person
{
    public function show(){
        echo "老年,免费<br>";
    }
}

class Check
{
    static function getResult($person){
        $person = new $person;
        $person->show();
    }
}

Check::getResult(‘minority‘);
Check::getResult(‘adult‘);
Check::getResult(‘elder‘);

适用场景:

1.多个类之区别在于表现行为不同,可以使用策略模式,在操作时动态选择要执行的策略。

2.需要在不同情况使用不同的策略,或者策略还可能在未来用其他方式实现。

3.对客户隐藏具体策略的实现细节,彼此完全独立。

推荐阅读:

PHP设计模式——策略模式

PHP设计模式之:策略模式

PHP设计模式之策略模式

PHP设计模式之策略模式

时间: 2024-10-11 16:39:33

php的设计模式的相关文章

Java设计模式——创建型模式之单例模式

一.概述 作为第一个出场的设计模式,有必要先介绍一下设计模式(引用自百度百科): 设计模式(Design Pattern)是一套被反复使用.多数人知晓的.经过分类的.代码设计经验的总结. 使用设计模式的目的:为了代码可重用性.让代码更容易被他人理解.保证代码可靠性. 设计模式使代码编写真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 设计模式概念的介绍,参见:http://blog.jobbole.com/101076/ 其中涉及的设计原则的概念,参见随笔:http://www.c

10大APP界面框架设计模式详解

随着移动互联网的发展,移动app已经成为了每个互联网公司的标配了,那作为产品经理,我们如何设计出更加符合用户体验的app产品呢?今天和大家分享的就是10中最常见的app界面光甲设计模式,一起来看看吧. 1.标签导航 标签导航是十大界面框架设计里最常用的界面框架设计,也是被业界之内公认的一种普遍使用的页面框架设计.那么这种页面框架设计在作业方面对一个用户来说也是最常见的一种页面框架设计,比如说微博.微信.手机百度.支付宝.淘宝,这些我们所谓的超级APP都是运用的标签导航,无一例外.从这个角度也可以

[js高手之路]设计模式系列课程-组合模式+寄生组合继承实战新闻列表

所谓组合模式,就是把一堆结构分解出来,组成在一起,现实中很多这样的例子,如: 1.肯德基套餐就是一种组合模式, 比如鸡腿堡套餐,一般是是由一个鸡腿堡,一包薯条,一杯可乐等组成的 2.组装的台式机同理,由主板,电源,内存条,显卡, 机箱,显示器,外设等组成的 把一个成型的产品组成部件,分成一个个独立的部件,这种方式可以做出很多灵活的产品,这就是组合模式的优势 比如:家用台式机电脑,要求配置比较低, 这个时候只需要主板+电源+内存条+机箱+显示器+外设就可以了,不需要配置独立显卡 鸡腿堡+鸡翅+紫薯

Happy 设计模式之适配器模式(JAVA)

设计模式-适配器模式 适配器模式定义 适配器模式,将一个类的的接口转换成客户或者产品希望的接口形式,就是原本不兼容或者甚至不相干的接口不能一起工作的接口一起工作,完成需求或者客户的需求. 适配器模式的使用场景 1.当你使用一个已经存在的类,而他的接口不符合你的需求. 2.你想要创建一个复用的类,该类可以与其相关的类或者不可见的类协同工作. 适配器角色 Target:目标接口 TargetImpl:目标实现类 Adapter:适配器 Adaptee:被适配者 代码解析: package com.d

设计模式 2/23 工厂模式

工厂模式是最常用的设计模式之一,用好了,代码优雅,可维护性高,对系统设计会上一个台阶 为什么这么说,因为工厂模式可以牵扯出抽象工厂模式,也有大家都会聊到的简单工厂模式 我们要了解一点,23中设计模式中,不包含简单工厂模式,之所以大家会去聊这个,四个字,渐进明细 通过对简单工厂模式的了解,我们引入工厂这个词,不然一个写代码的,天天给他讲工厂,工厂,工厂,西厂,东厂,会晕 同时,通过逐步的深入,从简单工厂,到工厂模式,再到抽象工厂,渐进明细的过程,逐步深入的理解,比较优劣,择优而为我们所用. 试想我

Java设计模式学习笔记,一:单例模式

开始学习Java的设计模式,因为做了很多年C语言,所以语言基础的学习很快,但是面向过程向面向对象的编程思想的转变还是需要耗费很多的代码量的.所有希望通过设计模式的学习,能更深入的学习. 把学习过程中的笔记,记录下来,只记干货. 第一部分:单例模式的内容 单例模式:类只能有一个实例. 类的特点:1.私有构造器:2.内部构造实例对象:3.对外提供获取唯一实例的public方法. 常见的单例模式实现有五种形式: 1.饿汉式. 2.懒汉式. 3.双重检查锁式. 4.静态内部类式. 5.枚举式. 以下分别

设计模式之单列模式

设计模式之单列模式 1,何为单列模式? 即singleton 在某个类采用了单列模式之后  其只能有一个实列对象 ,并且这个实列对象只能有内部自己创建并提供给外部的调用. 2.实现单列模式的方法 分为 :饿汉式 ,懒汉式 下面为饿汉式实现代码: public calss Singleton1{ //将构造函数私有化 防止外部通过new来创建对象 private Singleton1(){ } //创建一个私有静态变量并直接初始化 类加载的时候直接创建对象 private static Singl

设计模式之原型模式(Prototype)

1.初识原型模式 大家都知道连锁机构是现在灰常流行的商业模式,比如咖啡之翼,那么假设咖啡之翼要在长春新建立一个分店,所经营的产品和以前在其他的城市已经存在的店经营的产品差不多,那么面向对象开发的角度怎么解决这个问题呢?难道要重新的实例化一个咖啡之翼的店??这显然不太好吧,咖啡之翼里面经营的产品(假设是属性吧)都需要重新写,这就是在做大量的重复工作啊,这显然是不符合OO开发思想的.遇到这样的情况,并不是重新建立一个类来解决这样的问题,而是通过设计模式中的"原型模式"来解决这种问题.是这种

对设计模式的总结之简单工厂与策略模式

前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓,本文就说说我对本人对简单工厂模式.策略模式的见解. 简单工厂模式与策略模式 简单工厂模式 工作中,常常遇到需要做一个功能(鸭子),这个功能中含有可控个数的子操作功能(鸭子叫,鸭子跑,鸭子飞),而且子功能在不同的情况下处理方式又不相同(成年鸭子/小鸭子叫,成年鸭子/小鸭子跑,成年鸭子/小鸭子飞).我

设计模式——介绍与工厂模式(扁平管理模式VS职业经理人模式)

本文主要对设计模式进行大概解说.特别是对工厂模式进行简明的解析: 一.设计模式的分类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.訪问者模式.中介者模式.解释器模式. 事实上还有两类:并发型模式和线程池模式. 二.设计模式的六大原则 1.开闭原则(Op