12.适配器模式
可以将截然不同的函数接口封装成统一的API
实际应用举例,php的数据库操作有mysql,mysqli,pdo 3种,可以用适配器模式统一成一致。类似的场景还有cache适配器,将memcache,redis,file,apc等不同的缓存函数,统一成一致。
实现方式,定义统一的接口,
//在一个文件中,可以有一个类,也可以写一个接口,这两个可以写在一个文件里面,然后生成几个类去继承这个接口
interface IDatabase{
//host 数据的连接IP地址
function connect($host, $user, $passwd, $dbname);
function query($sql);
function close();
}
然后在对应的文件里面继承这个接口,然后按照各自的规则实现定义的这几个类。
去创建对应的适配器实例。
然后调用的时候,就看引入那个数据类型的文件,就使用对应的方法。
//适配器模式的封装
$db = new Imooc\Database\Mysql();
$db->connect('127.0.0.1', 'root', 'root', 'test');
$db->query("show databases");
$db->close();
13.策略模式
将一组特定的行为和算法封装成类,以适应某些特定的上下文环境,这种模式就是策略模式。
实际:加入一个电商网站系统,针对男女性用户要各自跳转到不同的商品类目,并把所有广告位展示不同的广告。
正常的开发中,都是用if else来判断男女加载不同的信息。
实现Ioc,依赖倒置,控制反转。
实现方式:
通过创建一个接口,把相应的方法定义出来,然后再创建对应的类来继承这个接口。并实现这些方法。
然后再使用的时候,根据实际情况调用对应的策略。然后先调用set方法来设置策略生成的的东西,然后index函数来展示。
class Page{
/**
* @var \Imooc\UserStrategy
*/
protected $strategy;
function index(){
echo "AD:";
$this->strategy->showAd();
echo "
";
echo "Category:";
$this->strategy->showCategory();
}
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();
控制反转:
可以很方便的替换两个相关联的类
14.数据对象映射模式
是将对象和数据存储映射起来,对一个对象操作会映射为对数据存储的操作。
在代码中实现数据对象映射模式,我们将实现一个ORM类,将复杂的SQL语句映射成对象属性的操作。
结合使用数据对象映射模式,工厂模式,注册模式。
这样就可以屏蔽底层的数据操作。
这个就是yii的model实现数据库操作的设计模式。
就是在控制器层不出现sql语句,然后再model里面,__construct
这个构造函数中创建数据库连接,然后在__destruct
析构函数中,将属性保存到数据库里面,使用sql的update操作。
15.观察者模式
但一个对象发生改变时,依赖他的对象全部会受到通知,并自动更新
场景:一个事务发生后,会执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新的逻辑增多之后,代码会变得难以维护,这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件主体的代码
观察者模式实现了低耦合,非侵入式的通知与更新机制
抽象类,本身没有任何代码,只有继承了他的子类,才会有逻辑
实现的例子,首先定义一个Observer的接口
namespace Imooc;
interface Observer
{
function update($event_info = null);
}
然后再定义一个EventGenerator的抽象类,Observer $observer这样的参数实际上是要传的就是一个Observer的对象,传进来的必须是一个对象,如果没有这个对象,可以直接new一个也行。然后就把所有的时间都保存进来,然后更改了方法的话,就通过notify里面,循环去通知所有的观察者的对象,这样就能实现低耦合了。
namespace Imooc;
abstract class EventGenerator
{
private $obserbers = array();
function addObserver(Observer $observer){
$this->obserbers[] = $observer;
}
function notify(){
foreach($this->obserbers as $obserber){
$obserber->update();
}
}
}
在index文件中测试的例子。写了两个观察者的类,然后实例化观察者接口中的update方法。然后加入观察者后,通过event里面去触发。
//观察者模式
class Event extends \Imooc\EventGenerator{
function trigger(){
echo "event";
//update
$this->notify();
}
}
class Observer1 implements \Imooc\Observer{
function update($event_info = null){
echo "逻辑1";
}
}
class Observer2 implements \Imooc\Observer{
function update($event_info = null){
echo "逻辑2";
}
}
$event = new Event;
$event->addObserver(new Observer1);
$event->addObserver(new Observer2);
$event->trigger();