一、工厂模式

1、创建接口类,规范方法,要实现这个接口的类必须实现这个接口的所有方法,接口的方法默认是抽象的,所以不再方法前面加 abstract

interface people{

  public function run() {};

}

2 、创建继承这个接口的类,创建工厂类

class superman implement people{

    public function run() {

         echo 'superman run';

    }

}

class women implement people{

    public function run() {

         echo 'women run';

    }

}

class factory {

public static function create($className) {

      return new $className()      

    }

}

factory::create('women')->run();

二、观察者模式

1、观察者可以向主题注册和解除注册,主题状态改变通过注册的观察者接口通知观察者,让观察者做相应的业务。

主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点! ——针对接口编程,不针对实现编程!

//定义观察者需要继承的接口

<?php
/**
* 3.1php设计模式-观测者模式
* 3.1.1概念:其实观察者模式这是一种较为容易去理解的一种模式吧,它是一种事件系统,意味
* 着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,
* 观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间
* 紧密耦合的另一种方法
* 3.1.2关键点:
* 1.被观察者->追加观察者;->一处观察者;->满足条件时通知观察者;->观察条件
* 2.观察者 ->接受观察方法
* 3.1.3缺点:
* 3.1.4观察者模式在PHP中的应用场合:在web开发中观察者应用的方面很多
* 典型的:用户注册(验证邮件,用户信息激活),购物网站下单时邮件/短信通知等
* 3.1.5php内部的支持
* SplSubject 接口,它代表着被观察的对象,
* 其结构:
* interface SplSubject
* {
* public function attach(SplObserver $observer);
* public function detach(SplObserver $observer);
* public function notify();
* }
* SplObserver 接口,它代表着充当观察者的对象,
* 其结构:
* interface SplObserver
* {
* public function update(SplSubject $subject);
* }
*/ /**
* 用户登陆-诠释观察者模式
*/
class User implements SplSubject {
//注册观察者
public $observers = array(); //动作类型
CONST OBSERVER_TYPE_REGISTER = 1;//注册
CONST OBSERVER_TYPE_EDIT = 2;//编辑 /**
* 追加观察者
* @param SplObserver $observer 观察者
* @param int $type 观察类型
*/
public function attach(SplObserver $observer, $type)
{
$this->observers[$type][] = $observer;
} /**
* 去除观察者
* @param SplObserver $observer 观察者
* @param int $type 观察类型
*/
public function detach(SplObserver $observer, $type)
{
if($idx = array_search($observer, $this->observers[$type], true))
{
unset($this->observers[$type][$idx]);
}
} /**
* 满足条件时通知观察者
* @param int $type 观察类型
*/
public function notify($type)
{
if(!empty($this->observers[$type]))
{
foreach($this->observers[$type] as $observer)
{
$observer->update($this);
}
}
} /**
* 添加用户
* @param str $username 用户名
* @param str $password 密码
* @param str $email 邮箱
* @return bool
*/
public function addUser()
{ //执行sql //数据库插入成功
$res = true; //调用通知观察者
$this->notify(self::OBSERVER_TYPE_REGISTER); return $res;
} /**
* 用户信息编辑
* @param str $username 用户名
* @param str $password 密码
* @param str $email 邮箱
* @return bool
*/
public function editUser()
{ //执行sql //数据库更新成功
$res = true; //调用通知观察者
$this->notify(self::OBSERVER_TYPE_EDIT); return $res;
}
} /**
* 观察者-发送邮件
*/
class Send_Mail implements SplObserver
{
/**
* 相应被观察者的变更信息
* @param SplSubject $subject
*/
public function update(SplSubject $subject)
{
$this->sendMail($subject->email, $title, $content);
} /**
*发送邮件
*@param str $email 邮箱地址
*@param str $title 邮件标题
*@param str $content 邮件内容
*/
public function sendEmail($email, $title, $content)
{
//调用邮件接口,发送邮件
}
}
?>

三、门面模式

门面模式


理解3个概念:

1)Container的概念,laravel所有的服务都注册在container里面,至于如何注册,就是使用service provider

2)service provider是用来绑定具体使用的服务,比如用MySQL数据库,还是Redis数据库,然后使用$this->app->bind进行绑定,以此实现松耦合,切换数据库比较方便。

3)facade用来提供统一的接口,比如无论你用哪种cache,redis还是
memcache,客户端都可以用cache::get()方式来获取value,至于具体是用了redis还是memcahe,就看你在sevice
provider里面绑定了哪个。cache::get()的实现方式是,继承Facade方法getFacadeAccessor,返回你在容器中绑定
的key值,比如cache,然后Facade类会使用php魔术变量__callstatic(),callstatic的逻辑里面会从
container里解析cache所绑定的服务,就是前面提到的service
provider绑定了谁。

这两个概念对于 Laravel 的使用者来说应该并不陌生,尤其是当你希望扩展或者替换 Laravel 核心库的时候,理解和合理使用它们可以极大提升 Laravel 的战斗力。这里以创建一个自己的 ServiceProvider 为例理解 Inversion of Control 和 Facade 在 Laravel 中的应用。

控制反转(Inversion of Control)

什么是 IoC

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入 (Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。 — 维基百科

简单说来,就是一个类把自己的的控制权交给另外一个对象,类间的依赖由这个对象去解决。依赖注入属于依赖的显示申明,而依赖查找则是通过查找来解决依赖。

Laravel 中的使用

注入一个类:

App::bind('foo', function($app)
{
return new FooBar;
});

这个例子的意思是创建一个别名为 foo 的类,使用时实际实例化的是 FooBar

使用这个类的方法是:

$value = App::make('foo');

$value 实际上是 FooBar 对象。

如果希望使用单例模式来实例化类,那么使用:

App::singleton('foo', function()
{
return new FooBar;
});

这样的话每次实例化后的都是同一个对象。

注入类的更多例子可以看 Laravel 官网

你可能会疑问上面的代码应该写在哪儿呢?答案是你希望他们在哪儿运行就写在哪儿。0 —— 0 知道写哪儿还用来看这种基础文章么!

服务提供器 (Service Providers)

为了让依赖注入的代码不至于写乱,Laravel 搞了一个 服务提供器(Service Provider)的东西,它将这些依赖聚集在了一块,统一申明和管理,让依赖变得更加容易维护。

Laravel 中的使用

定义一个服务提供器:

use Illuminate\Support\ServiceProvider;

class FooServiceProvider extends ServiceProvider {

    public function register()
{
$this->app->bind('foo', function()
{
return new Foo;
});
} }

这个代码也不难理解,就是申明一个服务提供器,这个服务提供器有一个 register的方法。这个方法实现了我们上面讲到的依赖注入。

当我们执行下面代码:

App::register('FooServiceProvider');

我们就完成一个注入了。但是这个还是得手动写,所以怎么让 Laravel 自己来做这事儿呢?

我们只要在 app/config/app.php 中的 providers 数组里面增加一行:

'providers' => [

‘FooServiceProvider’,
],

这样我们就可以使用 App::make(‘foo’) 来实例化一个类了。

你不禁要问了,这么写也太难看了吧?莫慌,有办法。

门面模式(Facade)

为了让 Laravel 中的核心类使用起来更加方便,Laravel实现了门面模式。

外觀模式(Facade pattern),是軟件工程中常用的一種軟件設計模式,它為子系統中的一組接口提供一個統一的高層接口,使得子系統更容易使用。 — 维基百科

Laravel 中的使用

我们使用的大部分核心类都是基于门面模式实现的。例如:

$value = Cache::get('key');

这些静态调用实际上调用的并不是静态方法,而是通过 PHP 的魔术方法__callStatic() 讲请求转到了相应的方法上。

那么如何讲我们前面写的服务提供器也这样使用呢?方法很简单,只要这么写:

use Illuminate\Support\Facades\Facade;

class Foo extends Facade {

    protected static function getFacadeAccessor() { return ‘foo’; }

}

这样我们就可以通过 Foo::test() 来调用我们之前真正的 FooBar 类的方法了。

别名(Alias)

有时候我们可能将 Facade 放在我们扩展库中,它有比较深的命名空间,如:\Library\MyClass\Foo。这样导致使用起来并不方便。Laravel 可以用别名来替换掉这么长的名字。

我们只要在 app/config/app.php 中 aliases 下增加一行即可:

'aliases' => [

'Foo' => ‘Library\MyClass\Foo’,
],

这样它的使用就由 \Library\MyClass\Foo::test() 变成 Foo::test() 了。

总结

所以有了控制反转(Inversion of Control)和门面模式(Facade),实际还有服务提供器(Service Providers)和别名(Alias),我们创建自己的类库和扩展 Laravel 都会方便很多。

这里总结一下创建自己类库的方法:

  1. 在 app/library/MyFoo 下创建类 MyFoo.php
  2. 在 app/library/MyFoo/providers 下创建 MyFooServiceProvider.php
  3. 在 app/library/MyFoo/facades 下创建 MyFooFacade.php
  4. 在 app/config/app.php 中添加 providers 和 aliases

四、数据访问对象模式

数据映射模式使您能更好的组织你的应用程序与数据库进行交互。

数据映射模式将对象的属性与存储它们的表字段间的结合密度降低。数据映射模式的本质就是一个类,它映射或是翻译类的属性或是方法到数据库的相应字段,反之亦然。

数据映射的作用(工作)就在于能对双方所呈现出的信息的理解,并能对信息的存取进行控制,如根据存储在数据表中的信息,重建新的域对象,或是用域对象的信息来更新或删除数据表中的相关数据。

对于面向对象代码与数据库表和字段间的映射关系的存储有多种实现方式。其中一种可能的方法就通过手工编码将这种映射关系存储在数据映射类中。

五、代理模式

1、定义共用接口,这样代理类在任何情况下都可以代理调用对应的方法

2、代理实现接口  被代理的类实现接口

3、代理类中的一个方法的参数传入判断调用各个被代理类

代码实现:<?php
/**
* Created by PhpStorm.
* User: LYL
* Date: 2015/5/16
* Time: 16:33
*/ /**顶层接口
* Interface IGiveGift
*/
interface IGiveGift
{
function giveRose();
function giveChocolate();
} /**追求者
* Class Follower
*/
class Follower implements IGiveGift
{
private $girlName; function __construct($name='Girl')
{
$this->girlName=$name;
} function giveRose()
{
echo "{$this->girlName}:这是我送你的玫瑰,望你能喜欢。<br/>";
} function giveChocolate()
{
echo "{$this->girlName}:这是我送你的巧克力,望你能收下。<br/>";
}
} /**代理
* Class Proxy
*/
class Proxy implements IGiveGift
{
private $follower; function __construct($name='Girl')
{
$this->follower=new Follower($name);
} function giveRose()
{
$this->follower->giveRose();
} function giveChocolate()
{
$this->follower->giveChocolate();
}
} 客户端代码: header("Content-Type:text/html;charset=utf-8");
//------------------------代理模式测试代码------------------
require_once "./Proxy/Proxy.php";
$proxy=new Proxy('范冰冰');
$proxy->giveRose();
$proxy->giveChocolate();

php 设计模式的更多相关文章

  1. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  2. java EE设计模式简介

    1.何为设计模式 设计模式提供了对常见应用设计问题的解决方案.在面向对象的编程中,设计模式通常在解决与对象创建和交互相关的问题,而非整体软件架构所面对的大规模问题,它们以样板代码的形式提供了通用的解决 ...

  3. 计算机程序的思维逻辑 (54) - 剖析Collections - 设计模式

    上节我们提到,类Collections中大概有两类功能,第一类是对容器接口对象进行操作,第二类是返回一个容器接口对象,上节我们介绍了第一类,本节我们介绍第二类. 第二类方法大概可以分为两组: 接受其他 ...

  4. 《JavaScript设计模式 张》整理

    最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...

  5. 《JavaScript设计模式与开发实践》整理

    最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...

  6. 设计模式之行为类模式大PK

                                        行为类模式大PK 行为类模式包括责任链模式.命令模式.解释器模式.迭代器模式.中介者模式.备忘录模式.观察者模式.状态模式.策略 ...

  7. .NET设计模式访问者模式

    一.访问者模式的定义: 表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作. 二.访问者模式的结构和角色: 1.Visitor 抽象访问者角色,为该 ...

  8. Java开发中的23种设计模式详解

    [放弃了原文访问者模式的Demo,自己写了一个新使用场景的Demo,加上了自己的理解] [源码地址:https://github.com/leon66666/DesignPattern] 一.设计模式 ...

  9. java 设计模式

    目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...

  10. 设计模式之单例模式(Singleton)

    设计模式之单例模式(Singleton) 设计模式是前辈的一些经验总结之后的精髓,学习设计模式可以针对不同的问题给出更加优雅的解答 单例模式可分为俩种:懒汉模式和饿汉模式.俩种模式分别有不同的优势和缺 ...

随机推荐

  1. Android入门(三):使用TextView、EditText 和Button接口组件

    我使用的IDE是Android Studio 2.1,虽然使用Eclipse也可以进行Android的开发,但是网上的大神大都推荐Android Studio,愿意了解的朋友可以参考知乎上关于Andr ...

  2. requerjs 合并 优化配置

    /* * This is an example build file that demonstrates how to use the build system for * require.js. * ...

  3. C# ArrayList的用法

    System.Collections.ArrayList类是一个特殊的数组.通过添加和删除元素,就可以动态改变数组的长度. 一.优点 1. 支持自动改变大小的功能 2. 可以灵活的插入元素 3. 可以 ...

  4. EmptyResultDataAccessException

    报此错误 :org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, act ...

  5. 普通用户ssh无密码登录设置

    这段时间在做Hadoop的环境配置,用root用户只需要按照一定的步骤进行操作就可以直接实现无密码登录,但如果使用新建用户,怎么尝试都不行. 本帖大部分都是其他人帖子的内容.如果按照下面的步骤还是不能 ...

  6. [转]关于AS3 Socket和TCP不得不说的三两事

    磨刀不误砍柴工,让我们从概念入手,逐步深入. 所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...

  7. ECMAScript 6(ES6)有什么新东西

    你可能已经听说过ECMAScript 6,JavaScript的下一个版本,它有一些非常棒的新功能.这些功能略微复杂,在简单的脚本和复杂的应用中都可以使用.在这篇文章中,我们将挑选一些ES6的功能进行 ...

  8. PHP基础知识之数组

    数组的定义: array( key => value , ... ) // 键(key)可以是一个整数或字符串,键可以省略,默认从0开始索引 // 值(value)可以是任意类型的值或者简写的方 ...

  9. Spring-Aop入门

    (一)Aop术语定义 1.通知(advice) 通知定义了切面要做什么工作,即调用的方法,同时定义了什么时候做这些工作,即以下五种类型 (1)前置通知(Before) :在目标方法调用之前执行切面方法 ...

  10. equals(),hashcode(),克隆学习心得

    equals(),hashcode(),克隆学习心得 其实在开发时候,很少去重写equals(),hashCode()方法,但是有些时候业务需要还是要重写. 注意: 重写equals()方法一定要重写 ...