1.策略模式
策略模式是对象的行为模式,用意是对一组算法的封装。
动态的选择需要的算法并使用。
策略模式指的是程序中涉及决策控制的一种模式。
abstract class UserAd { //抽象策略类
abstract function showAd();
}
//用于男性客户调用的类(环境角色)
class MaleUser extends UserAd {
function showAd() {
return '电脑数码|电子产品';
}
}
//用于女性客户调用的类(环境角色)
class FemaleUser extends userAd {
function showAd() {
return '服装分类|化妆品';
}
}
class User { //具体策略角色
public function call($object) {
return $object->showAd();
}
}
$user = new User ();
echo $user->call(new MaleUser());
echo PHP_EOL;
echo $user->call(new FemaleUser());
2.单例模式
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
单例模式是一种常见的设计模式,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、数据库操作、显卡的驱动程序常被设计成单例。
单例模式分3种:懒汉式单例、饿汉式单例、登记式单例。
单例模式有以下3个特点:
2.1.只能有一个实例。
2.2.必须自行创建这个实例。
2.3.必须给其他对象提供这一实例。
class Single {
private $name; //声明一个私有的实例变量
private function __construct(){ //声明私有构造方法为了防止外部代码使用new来创建对象。
}
static public $instance; //声明一个静态变量(保存在类中唯一的一个实例)
static public function getinstance(){ //声明一个getinstance()静态方法,用于检测是否有实例对象
if(!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function setname($text){
$this->name = $text;
}
public function getname(){
return $this->name;
}
}
$oa = Single::getinstance();
$ob = Single::getinstance();
$oa->setname('hello world');
$ob->setname('good morning');
echo $oa->getname();
echo $ob->getname();
3.责任链模式
责任链模式是一种设计模式。
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
请求在这个链上传递,直到链上的某一个对象决定处理此请求。
发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
/**
* 抽象处理者角色
*/
abstract class Handler{
protected $next;
/**
* 设置下一责任者
* @param Handler $handler
* @return void
*/
public function setNext(Handler $handler)
{
$this->next = $handler;
return $this;
}
abstract public function operate();
}
/**
* 具体处理者角色|员工
*/
class Staff extends Handler{ //员工申请
public function __construct()
{
}
public function operate()
{
echo '员工申请' . PHP_EOL; //当前责任者处理
if(is_null($this->next) == false){
$this->next->operate();
}
}
}
/**
* 具体处理者角色|总监
*/
class Director extends Handler{ //总监审批
public function __construct()
{
}
public function operate()
{
echo '总监审批' . PHP_EOL; //当前责任者处理
if(is_null($this->next) == false){
$this->next->operate();
}
}
}
/**
* 具体处理者角色|经理
*/
class Manager extends Handler{ //经理复批
public function __construct()
{
}
public function operate()
{
echo '经理复批' . PHP_EOL; //当前责任者处理
if(is_null($this->next) == false){
$this->next->operate();
}
}
}
$staff = new Staff();
$director = new Director();
$manager = new Manager();
$staff->setNext($director);
$director->setNext($manager);
$staff->operate();
4.工厂模式
工厂模式是我们最常用的实例化对象模式,是用工厂方法代替new操作的一种模式。
使用工厂模式的好处是,如果你想要更改所实例化的类名等,则只需更改该工厂方法内容即可,不需逐一寻找代码中具体实例化的地方(new处)修改了。
为系统结构提供灵活的动态扩展机制,减少了耦合。
/**
* 人类
*/
interface people
{
public function say();
}
class man implements people
{
//具体实现people的say方法
public function say()
{
echo '我是男人<br>';
}
}
class women implements people
{
//具体实现people的say方法
public function say()
{
echo '我是女人<br>';
}
}
/**
* 工厂类
*/
class SimpleFactoty
{
//用于创建男人对象
static function createMan()
{
return new man();
}
//用于创建女人对象
static function createWomen()
{
return new women();
}
}
//具体调用
$man = SimpleFactoty::createMan();
$man->say();
$woman = SimpleFactoty::createWomen();
$woman->say();
5.注册模式
注册树模式当然也叫注册模式,注册器模式。
注册树模式通过将对象实例注册到一棵全局的对象树上,需要的时候从对象树上采摘的模式设计方法。
这让我想起了小时候买糖葫芦,卖糖葫芦的将糖葫芦插在一个大的杆子上,人们买的时候就取下来。不同的是,注册树模式摘下来还会有,能摘很多次,糖葫芦摘一次就没了。。。
class Registry {
protected static $store = [];
private static $instance;
public static function instance() {
if(!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function isValid($key) {
return array_key_exists($key, Registry::$store);
}
public function get($key) {
if (array_key_exists($key, Registry::$store))
return Registry::$store[$key];
}
public function set($key, $obj) {
Registry::$store[$key] = $obj;
}
}
class ConnectDB {
private $host;
private $username;
private $password;
private $conn;
public function __construct($host, $username, $password){
$this->host = $host;
$this->username = $username;
$this->password = $password;
}
public function getConnect() {
return mysql_connect($this->host,$this->username,$this->password);
}
}
//使用测试
$reg = Registry::instance();
$reg->set('db1', new ConnectDB('localhost', 'root', 'Liu'));
$reg->set('db2', new ConnectDB('192.168.1.198', 'test', '0K5Dt@2jdc8#x@'));
print_r($reg->get('db1'));
print_r($reg->get('db2'));
6.观察者模式
当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。
场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新得逻辑增多之后,代码会变得难以维护.这种方式是耦合的,侵入式的,增加新的逻辑需要改变事件主题的代码
观察者模式实现了低耦合,非侵入式的通知与更新机制
/**
* 事件产生类
* Class EventGenerator
*/
abstract class EventGenerator
{
private $ObServers = [];
//增加观察者
public function add(ObServer $ObServer)
{
$this->ObServers[] = $ObServer;
}
//事件通知
public function notify()
{
foreach ($this->ObServers as $ObServer) {
$ObServer->update();
}
}
}
/**
* 观察者接口类
* Interface ObServer
*/
interface ObServer
{
public function update($event_info = null);
}
/**
* 观察者1
*/
class ObServer1 implements ObServer
{
public function update($event_info = null)
{
echo "观察者1 收到执行通知 执行完毕!\n";
}
}
/**
* 观察者1
*/
class ObServer2 implements ObServer
{
public function update($event_info = null)
{
echo "观察者2 收到执行通知 执行完毕!\n";
}
}
/**
* 事件
* Class Event
*/
class Event extends EventGenerator
{
/**
* 触发事件
*/
public function trigger()
{
//通知观察者
$this->notify();
}
}
//创建一个事件
$event = new Event();
//为事件增加旁观者
$event->add(new ObServer1());
$event->add(new ObServer2());
//执行事件 通知旁观者
$event->trigger();
7.适配器模式
把对某些相似的类的操作转化为一个统一的“接口”(这里是比喻的说话)–适配器,或者比喻为一个“界面”,统一或屏蔽了那些类的细节。
适配器模式还构造了一种“机制”,使“适配”的类可以很容易的增减,而不用修改与适配器交互的代码,符合“减少代码间耦合”的设计原则。
//目标角色
interface Targer
{
public function name();
public function voice();
}
//需要被适配的类(Adaptee)
Class Dog
{
public function name()
{
echo "dog \n";
}
public function voice()
{
echo "汪汪汪... \n";
}
}
//需要被适配的类(Adaptee)
Class Cat
{
public function name()
{
echo "cat \n";
}
public function voice()
{
echo "喵喵喵... \n";
}
}
//适配器
Class Adapter implements Targer
{
private $adaptee;
public function __construct($adaptee)
{
$this->adaptee = $adaptee;
}
public function name()
{
//以少量的代码对被适配者作出适配
echo 'name :';
$this->adaptee->name();
}
public function voice()
{
echo 'voice :';
$this->adaptee->voice();
}
}
$dog = new Adapter(new Dog);
$dog->name();
$dog->voice();
$cat = new Adapter(new Cat);
$cat->name();
$cat->voice();