胡桃仁

虚度光阴27 载

工厂方法(Factory Method)—-对象创建型模式

1、介绍

网上流行将工厂模式分为三类:

  • 简单工厂模式(simple factory pattern)
  • 工厂方法模式
  • 抽象工厂模式

书看的不太认真,没看到简单工厂模式,当然也不止这些,没看到的内容太多了。

简单工厂模式

1
2
// 消息接口
interface Msg{}
1
2
3
4
5
6
7
// 发送短信消息类
class SmsMsg implements Msg {
public function __construct()
{
echo "初始化一个短信消息内容</br>";
}
}
1
2
3
4
5
6
7
// 发送微信消息类
class WexinMsg implements Msg {
public function __construct()
{
echo "初始化一个微信消息内容</br>";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 专门给客户端(业务代码)用来创建消息类对象的
class MsgFactory {
public static function prepareSmsMsg(): SmsMsg {
return new SmsMsg();
}

public static function prepareWexinMsg(): WexinMsg {
return new WexinMsg();
}
public static function prepare ($type):Msg {
if ($type == "sms") {
return self::prepareSmsMsg();
} else if ($type == "wexin") {
return self::prepareWexinMsg();
} else {
return null;
}
}
}

// 测试一下
$smsMsg = MsgFactory::prepare("sms");

工厂方法

  • 1、意图

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

  • 2、动机

    框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。

假如是一个发送消息的功能,需要MsgBody组装消息体,不同身份的人的消息不一样, 和MsgSend消息发送 两个动作(发送的渠道不同,可能事短信、可能是微信)。则需要两个类都是作为抽象的(可以是abstract class),然后发送具体哪一种消息时,使用的类则继承自这两个抽象的类。

  • 3、实例
    1
    2
    3
    4
    // 消息接口
    interface Msg{
    public function body();
    }

+++++++++++++++++++++++++++++++++++++++
+++++ 下面是四种消息内容 +++++++++++++
+++++++++++++++++++++++++++++++++++++++

1
2
3
4
5
6
7
8
9
10
11
12
13
// 领导发送的微信消息内容类
class LeaderWeixinMsg implements Msg
{
public function __construct()
{
echo "初始化一个领导的微信消息内容</br>";
}

public function body()
{
echo "领导的微信消息内容</br>";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 领导发送的短信消息内容类
class LeaderSmsMsg implements Msg
{
public function __construct()
{
echo "初始化一个领导的短信消息内容</br>";
}

public function body()
{
echo "领导的短信消息内容</br>";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 员工发送的微信消息内容类
class StaffWeixinMsg implements Msg
{
public function __construct()
{
echo "初始化一个员工的微信消息内容</br>";
}

public function body()
{
echo "员工的微信消息内容</br>";
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
// 员工发送的短信消息内容类
class StaffSmsMsg implements Msg
{
public function __construct()
{
echo "初始化一个员工的短信消息内容</br>";
}

public function body()
{
echo "员工的短信消息内容</br>";
}
}

下面这个是发送渠道的抽象

1
2
3
4
// 消息发送工厂(在选择发送方式时,它是发送方式的抽象)
abstract class MsgFactory {
public abstract function createMsg($sender_type):Msg;
}

++++++++++++++++++++++++++++++++++++++++++++
++++++++++ 实现两种发送消息途径的类 ++++++++++
++++++++++++++++++++++++++++++++++++++++++++

1
2
3
4
5
6
7
8
9
10
11
12
// 发送微信消息的工厂
class SmsMsgFactory extends MsgFactory
{
public function createMsg($sender_type): Msg
{
if($sender_type == 'leader') {
return new LeaderWeixinMsg();
} else if($sender_type == 'staff') {
return new StaffWeixinMsg();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// 发送短信消息的工厂
class WexinMsgFactory extends MsgFactory
{
public function createMsg($sender_type): Msg
{
if($sender_type == 'leader') {
return new LeaderSmsMsg();
} else if($sender_type == 'staff') {
return new StaffSmsMsg();
}
}
}
1
2
3
4
// 测试一下
$wexinMsgFactory = new WexinMsgFactory();
$wexinMsg = $wexinMsgFactory->createMsg("staff"); // 员工想要发送微信消息
$wexinMsg->body();

createMsg 是一个工厂方法(factory method),因为它负责“生产” 一个对象。

  • 4、适用性

    当一个类不知道她所必须创建的对象的类的时候。
    当一个类希望由它的子类来指定它所创建的对象的时候。
    当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类
    是代理者这一信息局部化的时候。

总结

简单工厂模式看样子是在工厂模式的基础上简化了的。

评论