我是靠谱客的博主 顺利背包,这篇文章主要介绍浅谈PHP中的工厂方法模式,现在分享给大家,希望可以做个参考。

本篇文章带大家了解一下PHP设计模式中的工厂方法模式。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。

上回说到,简单工厂不属于GoF的二十三种设计模式,这回可就来真家伙了,大名顶顶的工厂方法模式前来报道!

GoF类图解释

工厂方法模式对比简单工厂来说,最核心的一点,其实就是将实现推迟到子类。怎么理解呢?我们可以将上回的简单工厂当做父类,然后有一堆子类去继承它。createProduct()这个方法在父类中也变成一个抽象方法。然后所有的子类去实现这个方法,不再需要用switch去判断,子类直接返回一个实例化的对象即可。

GoF定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化推迟到其子类。

GoF类图:

1.gif

  • 类图中的Product为产品
  • 类图中的Creator为创建者
  • 创建者父类有一个抽象的FactoryMethod()工厂方法
  • 所有创建者子类需要实现这个工厂方法,返回对应的具体产品
  • 创建者父类可以有一个AnOperation()操作方法,直接返回product,可以使用FactoryMethod()去返回,这样外部只需要统一调用AnOperation()

代码实现

首先是商品相关的接口和实现类,和简单工厂的类似:

复制代码
1
2
3
4
5
6
7
8
9
10
11
// 商品接口 interface Product{ function show() : void; } // 商品实现类A class ConcreteProductA implements Product{ public function show() : void{ echo "I'm A.n"; } }
登录后复制

接下来是创建者的抽象和实现类:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 创建者抽象类 abstract class Creator{ // 抽象工厂方法 abstract protected function FactoryMethod() : Product; // 操作方法 public function AnOperation() : Product{ return $this->FactoryMethod(); } } // 创建者实现类A class ConcreteCreatorA extends Creator{ // 实现操作方法 protected function FactoryMethod() : Product{ return new ConcreteProductA(); } }
登录后复制

这里和简单工厂就有了本质的区别,我们去掉了恶心的switch,让每个具体的实现类来进行商品对象的创建。没错,单一和封闭,每个单独的创建者子类只在工厂方法中和一个商品有耦合,有没有其他商品和其他的工厂来跟客户合作过这个子类完全不知道。

同样还是拿手机来比喻:我是一个卖手机的批发商(客户Client,业务方),我需要一批手机(产品ProductA),于是我去让富X康(工厂Creator)来帮我生产。我跟富士康说明了需求,富士康说好的,让我的衡阳工厂(ConcreteCreatorA)来搞定,不需要总厂上,你这小单子,洒洒水啦。然后过了一阵我又需要另一种型号的手机(产品ProductB),富士康看了看后又让郑州富士康(ConcreteCreatorB)来帮我生产。反正不管怎么样,他们总是给了我对应的手机。而且郑州工厂并不知道衡阳工厂生产过什么或者有没有跟我合作过,这一切只有我和总工厂知道。

实例

场景:光说不练假把式,把上回的短信发送改造改造,我们依然还是使用上回的那几个短信发送商。毕竟大家已经很熟悉了嘛,不过以后要更换也说不定,商场如战场,大家还是利益为先。这样的话,我们通过工厂方法模式来进行解耦,就可以方便的添加修改短信提供商咯。

短信发送类图

2.gif

代码实现

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php interface Message { public function send(string $msg); } class AliYunMessage implements Message{ public function send(string $msg){ // 调用接口,发送短信 // xxxxx return '阿里云短信(原阿里大鱼)发送成功!短信内容:' . $msg; } } class BaiduYunMessage implements Message{ public function send(string $msg){ // 调用接口,发送短信 // xxxxx return '百度SMS短信发送成功!短信内容:' . $msg; } } class JiguangMessage implements Message{ public function send(string $msg){ // 调用接口,发送短信 // xxxxx return '极光短信发送成功!短信内容:' . $msg; } } abstract class MessageFactory{ abstract protected function factoryMethod(); public function getMessage(){ return $this->factoryMethod(); } } class AliYunFactory extends MessageFactory{ protected function factoryMethod(){ return new AliYunMessage(); } } class BaiduYunFactory extends MessageFactory{ protected function factoryMethod(){ return new BaiduYunMessage(); } } class JiguangFactory extends MessageFactory{ protected function factoryMethod(){ return new JiguangMessage(); } } // 当前业务需要使用百度云 $factory = new BaiduYunFactory(); $message = $factory->getMessage(); echo $message->send('您有新的短消息,请查收');
登录后复制

说明

  • 和类图完全一致,基本不需要什么说明了吧,注意工厂方法模式的特点,实现推迟到了子类!!
  • 业务调用的时候需要耦合一个Factory子类。确实是这样,如果你想一个统一的出口来调用,请在外面加一层简单工厂就好啦,这就当成一道思考题吧
  • 不拘泥于目前的形式,可以不用抽象类,直接用一个接口来定义工厂方法,摒弃掉getMessage()方法,外部直接调用公开的模板方法(factoryMethod)即可

推荐学习:《PHP视频教程》

以上就是浅谈PHP中的工厂方法模式的详细内容,更多请关注靠谱客其它相关文章!

最后

以上就是顺利背包最近收集整理的关于浅谈PHP中的工厂方法模式的全部内容,更多相关浅谈PHP中内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(93)

评论列表共有 0 条评论

立即
投稿
返回
顶部