设计模式の行为型の策略模式

基本概念

策略模式是一个非常常用,且非常有用的设计模式。
简单的说,它是当你使用大量 if else 逻辑时的救星。
if else 就是一种判断上下文的环境所作出的策略,如果你把 if else 写死,那么在复杂逻辑的时候你会发现代码超级长,而且最蛋疼的是,当你以后要新增策略时,再写一个 elseif?
万一这个逻辑要修改 20 个地方呢?
一口老血吐在屏幕上…
策略模式就是来解决这个问题的。
举一个场景,商城的首页,男的进来看男性商品,女的进来看女性商品,不男不女…以此类推,各种条件下用不同策略展示不同商品。

设计模式の行为型の责任链模式

理解概念

责任链是一种比较高级的行为设计模式,就是当你有一个请求,你不知道用那个方法(handler)来处理这个请求时,你可以把这个请求丢进一个责任链里(里面有很多方法),这个责任链会通过轮询的方式自动找到对应的方法。

比如我要翻译一个单词,我写这个代码的时候,根本不知道用户会输入什么语言,所以我干脆就不管了,无论用户输入什么语言,我把它输入的内容丢进一个责任链,这个责任链里有德语翻译器,英语翻译器,法语翻译器,汉语翻译器,日语翻译器等等等等,丢进去的时候它就会自动查找了,找到对应的语言就会自动翻译出来。

设计模式の行为型の观察者模式

大概说明

如果我希望一个动作在发生的时候,希望订阅他这个动作的所有人都知道了有这么一件事的话,那么就采用观察者模式。

没用观察者模式的情况下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Event
{
function trigger()
{
echo "Event update!<br/>";

//具体更新逻辑

echo "update1<br/>";

echo "update2<br/>";

// ...
}
}

//使用
$event = new Event;

$event->trigger();

这个事件的触发可以看到如果我不断的有新的人需要订阅的话,那么这个 trigger 方法不断的就是要添加新的逻辑和业务。违反了设计模式-开闭原则,就是对修改关闭,对扩展开放的原则。

设计模式の装饰器模式和观察者模式的区别

观察者模式

观察者模式完美的将观察者和被观察对象分开,系统中的每个类将重点放在某一个功能上,而不是其他的方面(对象之间的交互),很好的体现了单一职责原则。观察者将自己注册到被观察者的容器中,被观察者不应该过问观察者的具体类型,而是使用观察者的接口。这样的优点是:假定程序中还有别的观察者,那么这个观察者是相同的接口即可,基于接口而不是具体的实现,这一点为程序提供了更大的灵活性。

现实生活中像移动的就业信息推送系统,希望得到业务的人(观察者)先到移动注册,然后如果有具体的信息,移动会主动的推送到预订业务的人,不需要预订业务的人去主动询问。

装饰者模式

装饰者模式不在不改变原类文件的情况下动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。当我们需要为某个对象动态地增加一个功能的或职责的时候,可以考虑使用装饰者模式;当某个对象的职责经常发生变化或者经常需要动态的增加职责,避免为了适应变化而增加爱继承子类扩展的方式,因为这种扩展可能会造成子类膨胀的速度过快,难以控制,此时可以使用装饰着模式。

对于这中模式的实现,会有被装饰的具体对象,被装饰的抽象,装饰者的抽象,和若干个装饰着,这若干个装饰者并不是创建各种不同的对象(所以装饰者模式为结构型模式而不是创建型模式),而是每个装饰者都会有一个真实的对象的引用,然后在这个具体对象方法的前后添加一些新的功能,起到装饰的作用。例如有两个装饰 1,和装饰 2,那么可以把装饰 1 当作装饰 2 的具体对象作为参数传进去,这个时候就会产生另外一种新的装饰了,而且没有新的子类。

现实生活着的例子例如包饺子,步骤分为和陷,和面,杆皮,包饺子,煮饺子,可以在和陷这个方法的前面多加点配菜,也可以在和面这个方法的前面在面里面加个鸡蛋,也可以同时用这两个装饰先加菜后和面加鸡蛋,这样就可以用两个已经存在的装饰产生一个新的装饰了。

设计模式の结构型の代理模式

大概意思

这个模式其实比较简单,就是你想访问一个类的时候,不直接访问,而是找这个类的一个代理。
代理就是中介,有中介就意味着解耦。

在代理模式下,代理对象和被代理的对象,有个重要特点:必须继承同一个接口。

这里说下重点,之前说过的 适配器模式,和代理模式非常非常像,只不过是在适配器模式下,适配器和它要适配的类没有继承同一接口,适配器就是要把这个第三方类变成符合接口规范。适配器也是个中介,所以我说它们很像。
实现

接口:

1
2
3
4
interface Image
{
public function getWidth();
}

现在我们有一个 Image 接口类,接口定义 getWidth 方法。现在我们需要一个具体类(实现类)来实现这个接口。

设计模式の结构型の链式模式

一个常见的非正统的设计模式

fluent interface(流利接口)有一个更广为人知的名字『链式操作』,可能大多数人大概都是从 Jquery 最先熟悉的,在 laravel 中,ORM 的一系列 sql 操作,也是链式操作,特点是每次都返回一个 Query Builder 对象。

设计模式の结构型の门面模式

概念

用过 Laravel 的朋友的应该熟悉,Laravel 给我们科普了一个概念 Facade,然而 Laravel 中的 Facade 并不是真正设计模式中定义的 Facade,那么为什么它们都叫一个名字呢?

我们还是先来了解一下 Facade 这个单词的意思吧。
首先它的读音是[fəˈsɑːd],源自法语 façade,法语这个词原意就是 frontage,意思是建筑的正面,门面,由于以前法国,意大利的建筑只注重修葺临街的一面,十分精美,而背后却比较简陋,所以这个词引申的意思是表象,假象。

先讲设计模式中的概念

在设计模式中,其实 Facade 这个概念十分简单。

它主要讲的是设计一个接口来统领所有子系统的功能。看完下面这个例子就明白了:

设计模式の结构型の依赖注入模式

很简单的理解

终于要讲到这个著名的设计原则,其实它比其他设计模式都简单。
依赖注入的实质就是把一个类不可能更换的部分 和 可更换的部分 分离开来,通过注入的方式来使用,从而达到解耦的目的。

一个数据库连接类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Mysql
{
private $host;
private $port;
private $username;
private $password;
private $db_name;

public function __construct()
{
$this->host = '127.0.0.1';
$this->port = 22;
$this->username = 'root';
$this->password = '';
$this->db_name = 'my_db';
}

public function connect()
{
return mysqli_connect($this->host, $this->username, $this->password, $this->db_name, $this->port);
}
}

设计模式の结构型の装饰器模式

大概的意思

一个类中有一个方法,我需要经常改它,而且会反反复复,改完了又改回去。 一般要么我们直接改原来的类中的方法,要么继承一下类覆盖这个方法。 有没有一个办法可以不用继承,只需要增加一个类进去,就可以改掉那个方法。 有,装饰器模式。

场景

1
2
3
4
5
6
7
8
9
10
11
class plainCoffee
{
public function makeCoffee()
{
$this->addCoffee();
}

public function addCoffee()
{
}
}

这是一个煮咖啡的程序,现在我还想加点糖,一般做法: