设计模式
来源:互联网 发布:盛世投资 知乎 编辑:程序博客网 时间:2024/05/29 02:48
SPL常用的数据结构类
1、栈-特点(先进后出)
入栈:
$stack = new SplStack(); $stack->push("data1\n"); $stack->push("data2\n");
出栈:
echo $stack->pop(); echo $stack->pop();
结果:
data2 data1
2、队列(先进先出)
入队:
$queue = new SplQueue(); $queue->enqueue("data1\n");
出队:
echo $queue->dequeue(); echo $queue->dequeue();
结果:
data1 data2
3、堆:最小堆使用,直接插入
存入:
$heap = new SplMinHeap(); $heap->insert("data1\n"); $heap->insert("data2\n");
提取:
echo $heap->extract(); echo $heap->extract();
结果:
data1 data2
4、固定长度数组
特点:无论下标是否有值 都分配内存空间保留位置
$array = new SplFixedArray(10); //输入长度值 $array[0] = 123; $array[9] = 234; var_dump($array);
PSR-0规范:
1.命名空间必须与绝对路径一致
2.类名首字母必须大写
3.除入口文件外,其他“.php”必须只有一个类 不能有可执行的代码
设计模式
工厂模式:
1.定义一个专门用来实例化其它对象的类。就是在一个类中封装一些new其他对象的方法,然后返回对象,这样在需要调用某个类的时候,我们就不需要去使用new关键字实例化这个类,而是通过我们的工厂类调用某个方法得到类的实例
2.好处:一旦发生变更,只需要在工厂类里面修改即可,而不用一个一个的去修改
eg:
<?php //定义一个工厂类 class Factory{ static function createDatabase(){ $db = new Database(); return $db; } } //在要实例化对象时只要调用工厂类的方法即可 <?php $db = IMooc\Factory::createDatabase();
单例模式:
1.避免重复实例化一个对象,造成资源浪费
2.步骤:
<1> 构造方法私有化
<2> 声明非公开的成员属性,用于判断类是否被实例化
<3> 声明静态的公有方法,来实例化对象并返回
eg:
<?php 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; } } //使用时调用共有方法实例化,不会多次实例化造成资源浪费 <?php $db = Database::getInstance();
注册器模式:
1. 已经创建好对象后,下次使用直接取,将一些对象注册到全局树上面,可以用来在任何地方被访问
2. 一般只提供一个set 和 unset 两种方法,需要一个静态的非公开属性和一个取得静态属性的静态方法
3.
<1> set():将对象隐射到全局树上,<2> _unset():从树上移除。<3> get():获取注册到树上的对象。<4> 在框架初始化的时候,会做注册器的初始化操作,然后可以在任何地方去访问注册器的方法。
eg: //注册器模式 <?php 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]); } } //在工厂模式下可以这样写 <?php class Factory{ static function createDatabase(){ $db =Database::getInstance(); //调用注册器注册到全局树 Register::set('db1', $db); return $db; } } //调用时 <?php $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实现接口的所有方法(不同的策略)
接口
<?php interface Userstrategy{ function showAD(); function showCategory(); }
两个实现不同策略的类
<?php class FemaleUserstrategy implements Userstrategy{ function showAD(){ echo "2015新女装"; } function showCategory(){ echo "女装"; } } <?php class MaleUserstrategy implements Userstrategy{ function showAD(){ echo "2015新男装"; } function showCategory(){ echo "男装"; } }
index文件:
<?php class Page{ protected $strategy; function index(){ echo "AD:"; $this->strategy->showAD(); echo "<br>"; echo "Category:"; $this->strategy->showCategory(); echo "<br>"; } function setStrategy(IMooc\Userstrategy $strategy){ $this->strategy = $strategy; } }
具体实现
<?php $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语句映射成对象属性的操作。结合使用数据对象映射模式,工厂模式,注册模式
对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping)
1. 一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。
2. 从效果上说,它其实是创建了一个可在编程语言里使用的–“虚拟对象数据库”。
3. 面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。简单的说:ORM相当于中继数据
观察者模式
好处: 在实际项目跨团队多人合作开发中,碰到多事件、多逻辑这种操作的时候,运用观察者模式能够有利于代码的维护!
======有待进一步研究==
1. 观察者模式(Observer),当一个对象状态发生改变时,依赖它的对象全部会收到通知,并自动更新。
2. 场景:一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件主体的代码。
3. 观察者模式实现了低耦合,非侵入式的通知与更新机制。
步骤:
<1> 观察者模式是首先定义一个接口,接口空方法做规范。
event.php:
<?php namespace IMooc; interface Observer{ function update($event_info = null); }
<2> 第二部写一个抽象类,抽象类定义了方法吊用接口的方法。
EventGenerator.php:
<?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
<?php namespace IMooc; class Event extends EventGenerator{ function trigger(){ echo "Event <br>"; $this->ontify(); } }
<4> 最后写观察者实现接口的方法。
Observer1.php
<?php class Observer1 implements Observer{ function update($event_info = null){ echo "逻辑1"; } }
Observer2.php
<?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:
<?php namespace IMooc; interface DrawDecorator { function beforeDraw(); function afterDraw(); }
<2> 在类中调用接口
Canvas.php:
<?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 "<br />\n"; } //调用方法实现接口 $this->afterDraw(); } }
3.声明装饰器类实现装饰器接口方法
ColorDrawDecorator.php:
<?php namespace IMooc; class ColorDrawDecorator implements DrawDecorator { protected $color; function __construct($color = 'red') { $this->color = $color; } function beforeDraw() { echo "<div style='color: {$this->color};'>"; } function afterDraw() { echo "</div>"; } } ```**SizeDrawDecorator.php** ``` <?php namespace IMooc; class SizeDrawDecorator implements DrawDecorator { protected $size; function __construct($size = '14px') { $this->size = $size; } function beforeDraw() { echo "<div style='font-size: {$this->size};'>"; } function afterDraw() { echo "</div>"; } }
4. 在使用对象时调用不同的装饰器方法即可实现修改原对象方法功能
<?php $canvas1 = new IMooc\Canvas(); $canvas1 -> addDecorator(new \INooc\ColorDrawDecorator('green')); $canvas1 -> addDecorator(new \IMooc\SizeDrawDecorator('10px')); $canvas1 -> draw();
迭代器模式
======有待进一步研究==
1. 迭代器模式,在不需要了解内部实现的前提下,遍历一个聚合对象的内部元素。
2. 相比传统的编程模式,迭代器模式可以隐藏遍历元素的所需操作。
实现
1. 实现Iterator接口
<?php 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. 定义一个接口
<?php namespace IMooc; interface IUserProxy { function getUserName($id); function setUserName($id, $name); }
2. 类中实现接口的方法
<?php 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.调用同一个实现对不同服务器数据库的操作
<?php $proxy = new \IMooc\Proxy(); $proxy->getUserName($id); $proxy->getUserName($id,$proxy);
面向对象编程
基本原则:
1,单一职责:一个类,只需要做好一件事情。2,开放封闭:一个类,应该是可扩展的,而不可修改的。3,依赖倒置:一个类,不应该强依赖另外一个类。每个类对于另外一个类都是可扩展的。(依赖注入)4,配置化:尽可能地使用配置,而不是硬编码5,面向接口编程:只需要关心接口,而不需要关心代码具体实现
MVC
模型--视图--控制器,一种C/S或者B/S软件工程的组织方式
模型(Model):数据和存储的封装
视图(View):展现层的封装,如Web系统中的模板文件
控制器(Controller):逻辑层的封装
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式~~~~~~~~~~
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- 设计模式
- C++标准IO操作
- 学习Linux命令(50)
- CxImage 702 在VS2015 编译和使用
- intellij配置hibernate自动生成hbm.xml文件
- Visual Studio中开发Jni dll库
- 设计模式
- python之环境下载与简单运行
- AD7190之STM32程序——STM32测试高精度ADC篇(三)
- java基础--for循环输出"*"号三角形
- java异常抛出解析,java抛出方法
- docker介绍
- 机器学习与深度学习(二) k最邻近分类算法 (K-Nearest Neighbor) KNN
- 安装
- 34 《避开错误决策的四个陷阱》 -豆瓣评分8.0