入栈:
$stack = new SplStack();
$stack->push("data1\n");
$stack->push("data2\n");
出栈:
echo $stack->pop();
echo $stack->pop();
结果:
data2
data1
入队:
$queue = new SplQueue();
$queue->enqueue("data1\n");
出队:
echo $queue->dequeue();
echo $queue->dequeue();
结果:
data1
data2
存入:
$heap = new SplMinHeap();
$heap->insert("data1\n");
$heap->insert("data2\n");
提取:
echo $heap->extract();
echo $heap->extract();
结果:
data1
data2
特点:无论下标是否有值 都分配内存空间保留位置
$array = new SplFixedArray(10); //输入长度值
$array[0] = 123;
$array[9] = 234;
var_dump($array);
1.命名空间必须与绝对路径一致
2.类名首字母必须大写
3.除入口文件外,其他“.php”必须只有一个类 不能有可执行的代码
1.定义一个专门用来实例化其它对象的类。就是在一个类中封装一些new其他对象的方法,然后返回对象,这样在需要调用某个类的时候,我们就不需要去使用new关键字实例化这个类,而是通过我们的工厂类调用某个方法得到类的实例
2.好处:一旦发生变更,只需要在工厂类里面修改即可,而不用一个一个的去修改
eg:
//定义一个工厂类
class Factory{
static function createDatabase(){
$db = new Database();
return $db;
}
}
//在要实例化对象时只要调用工厂类的方法即可
$db = IMooc\Factory::createDatabase();
1.避免重复实例化一个对象,造成资源浪费
2.步骤:
<1> 构造方法私有化
<2> 声明非公开的成员属性,用于判断类是否被实例化
<3> 声明静态的公有方法,来实例化对象并返回
eg:
class Singleton{
//私有化内部实例化的对象
private static $instance = null; //私有化构造方法,禁止外部实例化对象
private function __construct()
{
}
//私有化__clone,防止对象被克隆
private function __clone(){}
// 公有静态实例方法
public static function getInstance()
//如果没有被实例化过,则实例化
if(self::$instance == null){
//内部实例化对象
self::$instance = new self();
//返回
return self::$instance;
}
}
//使用时调用共有方法实例化,不会多次实例化造成资源浪费
$db = Database::getInstance();
1. 已经创建好对象后,下次使用直接取,将一些对象注册到全局树上面,可以用来在任何地方被访问
2. 一般只提供一个set 和 unset 两种方法,需要一个静态的非公开属性和一个取得静态属性的静态方法
3.
<1> set():将对象隐射到全局树上,
<2> _unset():从树上移除。
<3> get():获取注册到树上的对象。
<4> 在框架初始化的时候,会做注册器的初始化操作,然后可以在任何地方去访问注册器的方法。
eg:
//注册器模式
class Register{
protected static $objects;
static function set($alias,$object){
self::$objects[$alias] = $object;
}
static function get($name){
return self::$objects[$name];
}
function _unset($alias){
unset(self::$objects[$alias]);
}
}
//在工厂模式下可以这样写
class Factory{
static function createDatabase(){
$db =Database::getInstance();
//调用注册器注册到全局树
Register::set('db1', $db);
return $db;
}
}
//调用时
$db1 = \IMooc\Register::get('db1');
======有待进一步研究==
1. 适配器模式,可以将截然不同的函数接口封装成统一的API
2. 实际应用举例,PHP数据库操作有mysql,mysqli,pdo三种,可以用适配器模式统一成一致。类似场景还有cache适配,将memcache,redis,file,apc等不同的缓存函数,统一成一致
======有待进一步研究==
1. 策略模式,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,这种模式就是策略模式
2. 定义一个策略接口文件,定义策略接口,声明策略
3. 如果上下文环境发生变化,只需要许改策略即可
4.定义具体类,实现策略接口,重写策略方法,
5. 分支逻辑if else,新增一个逻辑以后需要修改每一个if else的地方。使用策略模式以后,只需要增加一个策略类。
6.实现了硬编码到解耦
7.策略模式可以实现IOC、依赖倒置、控制反转。
8. page类依赖于MaleUserStratey这个类,但不需要在page类中实现MaleUserStratey,只有再使用时才绑定,这样以后更方便的替换修改MaleUserStratey类,实现了两个类的解耦,这就是策略模式的依赖倒置
eg:
UserStrategy.php 策略的接口文件:约定策略的所有行为。
FemaleUserStrategy.php 实现接口的所有方法(不同的策略)
MaleUserStrategy.php实现接口的所有方法(不同的策略)
接口
interface Userstrategy{
function showAD();
function showCategory();
}
两个实现不同策略的类
class FemaleUserstrategy implements Userstrategy{
function showAD(){
echo "2015新女装";
}
function showCategory(){
echo "女装";
}
}
class MaleUserstrategy implements Userstrategy{
function showAD(){
echo "2015新男装";
}
function showCategory(){
echo "男装";
}
}
index文件:
class Page{
protected $strategy;
function index(){
echo "AD:";
$this->strategy->showAD();
echo "
";
echo "Category:";
$this->strategy->showCategory();
echo "
";
}
function setStrategy(IMooc\Userstrategy $strategy){
$this->strategy = $strategy;
}
}
具体实现
$page = new Page;
//实现不同的策略
if(isset($_GET['female'])){
$strategy = new \IMooc\FemaleUserstrategy();
}else{
$strategy = new \IMooc\MaleUserstrategy();
}
$page->setStrategy($strategy);
$page->index();
======有待进一步研究==
1. 数据对象映射模式,是将对象和数据存储映射起来,对一个对象的操作会映射为对数据存储的操作,比我们在代码中new一个对象,那么使用该模式就可以将对对象的一些操作,比如说我们设置的一些属性,它就会自动保存到数据库,跟数据库中表的一条记录对应起来
2. 实例,在代码中实现数据对象映射模式,我们将写一个ORM类,将复杂的SQL语句映射成对象属性的操作。结合使用数据对象映射模式,工厂模式,注册模式
1. 一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
2. 从效果上说,它其实是创建了一个可在编程语言里使用的–“虚拟对象数据库”。
3. 面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。简单的说:ORM相当于中继数据
好处: 在实际项目跨团队多人合作开发中,碰到多事件、多逻辑这种操作的时候,运用观察者模式能够有利于代码的维护!
======有待进一步研究==
1. 观察者模式(Observer),当一个对象状态发生改变时,依赖它的对象全部会收到通知,并自动更新。
2. 场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件主体的代码。
3. 观察者模式实现了低耦合,非侵入式的通知与更新机制。
步骤:
<1> 观察者模式是首先定义一个接口,接口空方法做规范。
event.php:
namespace IMooc;
interface Observer{
function update($event_info = null);
}
<2> 第二部写一个抽象类,抽象类定义了方法吊用接口的方法。
EventGenerator.php:
abstract class EventGenerator{
private $obserers = array();
function addObsever(Observer $observer){
$this->obserers[] = $observer;
}
function ontify(){
foreach ($this->obserers as $observer){
$observer->update();
}
}
}
<3> 写一个子类继承抽象类,然后写个新方法吊用抽象类里面吊用接口的方法。
event.php
namespace IMooc;
class Event extends EventGenerator{
function trigger(){
echo "Event
";
$this->ontify();
}
}
<4> 最后写观察者实现接口的方法。
Observer1.php
class Observer1 implements Observer{
function update($event_info = null){
echo "逻辑1";
}
}
Observer2.php
class Observer1 implements Observer{
function update($event_info = null){
echo "逻辑2";
}
}
======有待进一步研究==
1. 原型模式与工厂模式作用类似,都是用来创建对象
2. 与工厂模式的实现不同,原型模式是先创建好一个原型对象,然后通过clone原型对象来创建新的对象,以减少new时的开销,这样就免去了类创建时重复的初始化操作,
3. 原型模式适用于大对象的创建,创建一个大对象需要很大的开销,如果每次new就会消耗很大,原型模式仅需内存拷贝即可
======有待进一步研究==
1. 装饰器模式(Decorator),可以动态地添加修改类的功能
2. 一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法
3. 使用装饰器模式,仅需在运行时添加一个装饰器对象即可实现,可以实现最大的灵活性
实现
<1> 写一个装饰器接口
DrawDecorator.php:
namespace IMooc;
interface DrawDecorator
{
function beforeDraw();
function afterDraw();
}
<2> 在类中调用接口
Canvas.php:
namespace IMooc;
class Canvas
{
//存装饰接口的属性
protected $decorators = array();
//接收并添加装饰接口
function addDecorator(DrawDecorator $decorator)
{
$this->decorators[] = $decorator;
}
//调用装饰器接口
function beforeDraw()
{
foreach($this->decorators as $decorator)
{
$decorator->beforeDraw();
}
}
//调用装饰器接口
function afterDraw()
{
//反转是因为before和after都存在的情况下需要一一对应
$decorators = array_reverse($this->decorators);
//遍历因为可能会有多个装饰器
foreach($decorators as $decorator)
{
$decorator->afterDraw();
}
}
//要修改功能的方法
function draw()
{
//可以在任何地方实现接口进行修改
//调用方法实现接口
$this->beforeDraw();
foreach($this->data as $line)
{
foreach($line as $char)
{
echo $char;
}
echo "
\n";
}
//调用方法实现接口
$this->afterDraw();
}
}
3.声明装饰器类实现装饰器接口方法
ColorDrawDecorator.php:
namespace IMooc;
class ColorDrawDecorator implements DrawDecorator
{
protected $color;
function __construct($color = 'red')
{
$this->color = $color;
}
function beforeDraw()
{
echo "";
}
function afterDraw()
{
echo "";
}
}
```
**SizeDrawDecorator.php**
```
namespace IMooc;
class SizeDrawDecorator implements DrawDecorator
{
protected $size;
function __construct($size = '14px')
{
$this->size = $size;
}
function beforeDraw()
{
echo "";
}
function afterDraw()
{
echo "";
}
}
4. 在使用对象时调用不同的装饰器方法即可实现修改原对象方法功能
$canvas1 = new IMooc\Canvas(); $canvas1 -> addDecorator(new \INooc\ColorDrawDecorator('green')); $canvas1 -> addDecorator(new \IMooc\SizeDrawDecorator('10px')); $canvas1 -> draw();
======有待进一步研究==
1. 迭代器模式,在不需要了解内部实现的前提下,遍历一个聚合对象的内部元素。
2. 相比传统的编程模式,迭代器模式可以隐藏遍历元素的所需操作。
实现
1. 实现Iterator接口
class AllUser implements Iterator{
}
2. 必须实现Iterator的五个接口
class AllUser implements Iterator{
function current(){
//返回当前元素
}
function key(){
//返回当前元素的键
}
function next(){
//移动到下一个元素
}
function rewind(){
//返回到迭代器的第一个u
}
function valid(){
//检查当前位置是否有效
}
}
3. 调用
$users = new \IMooc\AllUser();
foreach($users as $user){
var_dump($user->name);
}
======有待进一步研究==
1. 在客户端与实体之间建立一个代理对象(proxy),客户端对实体进行操作全部委派代理对象,隐藏实体的具体实现细节;
2.proxy还可以与业务代码分离,部署到另外的服务器。业务代码中通过RPC来委派任务
实现(只是举例):
1. 定义一个接口
namespace IMooc;
interface IUserProxy
{
function getUserName($id);
function setUserName($id, $name);
}
2. 类中实现接口的方法
namespace IMooc;
class Proxy implements IUserProxy
{
function getUserName($id)
{
//创建不同的数据库对象以实现读数据库读写分离
$db = Factory::getDatabase('slave');
$db->query("select name from user where id =$id limit 1");
}
function setUserName($id, $name)
{
$db = Factory::getDatabase('master');
$db->query("update user set name = $name where id =$id limit 1");
}
}
3.调用同一个实现对不同服务器数据库的操作
$proxy = new \IMooc\Proxy(); $proxy->getUserName($id); $proxy->getUserName($id,$proxy);
基本原则:
1,单一职责:一个类,只需要做好一件事情。
2,开放封闭:一个类,应该是可扩展的,而不可修改的。
3,依赖倒置:一个类,不应该强依赖另外一个类。每个类对于另外一个类都是可扩展的。(依赖注入)
4,配置化:尽可能地使用配置,而不是硬编码
5,面向接口编程:只需要关心接口,而不需要关心代码具体实现
模型--视图--控制器,一种C/S或者B/S软件工程的组织方式
模型(Model):数据和存储的封装
视图(View):展现层的封装,如Web系统中的模板文件
控制器(Controller):逻辑层的封装