乐趣区

关于php:PHP设计模式之抽象工厂模式

工厂模式系列中的重头戏来了,没错,那正是传闻中的 形象工厂模式 。首次听到这个名字的时候你有什么感觉?反正我是感觉这货应该是十分高大上的,毕竟蕴含着“形象”两个字。话说这两个字在开发中真的是有点高大上的感觉,一带上形象两字就如同哪哪都很厉害了呢。不过, 形象工厂 也的确能够说是工厂模式的大哥大。

Gof 类图及解释

其实只有了解了工厂办法模式,就很容易明确形象工厂模式。怎么说呢?还是一样的提早到子类,还是一样的返回指定的对象。只是形象工厂外面不仅仅只返回一个对象,而是返回一堆。

GoF 定义:提供一个创立一系列相干或相互依赖对象的接口,而无需指定它们具体的类。

GoF 类图

  • 右边是两个工厂 1 和 2,都继承一个形象工厂,都实现了 CreateProductA 和 CreateProductB 办法
  • 工厂 1 生产的是 ProductA1 和 ProductB1
  • 同样的,工厂 2 生产的是 ProductA2 和 ProductB2

代码实现

// 商品 A 形象接口
interface AbstractProductA
{public function show(): void;
}

// 商品 A1 实现
class ProductA1 implements AbstractProductA
{public function show(): void
    {echo 'ProductA1 is Show!' . PHP_EOL;}
}
// 商品 A2 实现
class ProductA2 implements AbstractProductA
{public function show(): void
    {echo 'ProductA2 is Show!' . PHP_EOL;}
}

// 商品 B 形象接口
interface AbstractProductB
{public function show(): void;
}
// 商品 B1 实现
class ProductB1 implements AbstractProductB
{public function show(): void
    {echo 'ProductB1 is Show!' . PHP_EOL;}
}
// 商品 B2 实现
class ProductB2 implements AbstractProductB
{public function show(): void
    {echo 'ProductB2 is Show!' . PHP_EOL;}
}

商品的实现,货色很多吧,这回其实是有四件商品了别离是 A1、A2、B1 和 B2,他们之间假如有这样的关系,A1 和 B1 是同类相干的商品,B1 和 B2 是同类相干的商品

// 形象工厂接口
interface AbstractFactory
{
    // 创立商品 A
    public function CreateProductA(): AbstractProductA;
    // 创立商品 B
    public function CreateProductB(): AbstractProductB;}

// 工厂 1,实现商品 A1 和商品 B1
class ConcreteFactory1 implements AbstractFactory
{public function CreateProductA(): AbstractProductA
    {return new ProductA1();
    }
    public function CreateProductB(): AbstractProductB
    {return new ProductB1();
    }
}

// 工厂 2,实现商品 A2 和商品 B2
class ConcreteFactory2 implements AbstractFactory
{public function CreateProductA(): AbstractProductA
    {return new ProductA2();
    }
    public function CreateProductB(): AbstractProductB
    {return new ProductB2();
    }
}

而咱们的工厂也是工厂 1 和工厂 2,工厂 1 生产的是 A1 和 B1 这两种相关联的产品,工厂 2 生产的是 A2 和 B2 这两种商品。好吧,我晓得这里还是有点形象,可能还是搞不懂为什么要这样,咱们持续以手机生产来举例。

咱们的手机品牌起来了,所以周边如手机膜、手机壳也交给了富 X 康(AbstractFactory)来帮我搞定。上回说到,我曾经有几款不同类型的手机了,于是还是按原来那样,衡阳工厂(Factory1)生产型号 1001 的手机(ProductA1),同时型号 1001 手机的手机膜(ProductB1)和手机壳(ProductC1)也是衡阳工厂生产进去。而型号 1002 的手机(ProductA2)还是在郑州工厂(Factory2),这个型号的手机膜(ProductB2)和手机膜(ProductC2)也就交给他们来搞定吧。于是,我还是只去跟总厂下单,他们让不同的工厂给我生产了一整套的手机产品,能够间接卖套装咯!!

残缺代码:形象工厂模式

实例

是不是看得还是有点晕。其实说简略点,真的就是在一个工厂类中通过不同的办法返回不同的对象而已。让咱们再次用发短信的实例来解说吧!

场景:这次咱们有个业务需要是,不仅要发短信,还要同时发一条推送。短信的目标是告诉用户有新的流动加入,而推送不仅告诉有新的流动,间接点击就能够进去领红包了,是不是很兴奋。还好之前咱们的抉择的云服务供应商都是即有短信也有推送接口的,所以咱们就间接用形象工厂来实现吧!

短信发送类图

<?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;
    }
}

interface Push {public function send(string $msg);
}

class AliYunPush implements Push{public function send(string $msg){
        // 调用接口,发送客户端推送
        // xxxxx
        return '阿里云 Android&iOS 推送发送胜利!推送内容:' . $msg;
    }
}

class BaiduYunPush implements Push{public function send(string $msg){
        // 调用接口,发送客户端推送
        // xxxxx
        return '百度 Android&iOS 云推送发送胜利!推送内容:' . $msg;
    }
}

class JiguangPush implements Push{public function send(string $msg){
        // 调用接口,发送客户端推送
        // xxxxx
        return '极光推送发送胜利!推送内容:' . $msg;
    }
}


interface MessageFactory{public function createMessage();
    public function createPush();}

class AliYunFactory implements MessageFactory{public function createMessage(){return new AliYunMessage();
    }
    public function createPush(){return new AliYunPush();
    }
}

class BaiduYunFactory implements MessageFactory{public function createMessage(){return new BaiduYunMessage();
    }
    public function createPush(){return new BaiduYunPush();
    }
}

class JiguangFactory implements MessageFactory{public function createMessage(){return new JiguangMessage();
    }
    public function createPush(){return new JiguangPush();
    }
}

// 以后业务须要应用阿里云
$factory = new AliYunFactory();
// $factory = new BaiduYunFactory();
// $factory = new JiguangFactory();
$message = $factory->createMessage();
$push = $factory->createPush();
echo $message->send('您曾经很久没有登录过零碎了,记得回来哦!');
echo $push->send('您有新的红包已到帐,请查收!');

残缺源码:短信发送工厂办法

阐明

  • 是不是很清晰了?
  • 没错,咱们有两个产品,一个是 Message,一个是 Push,别离是发信息和发推送
  • 形象工厂只是要求咱们的接口实现者必须去实现两个办法,返回发短信和发推送的对象
  • 你说我只想发短信不想发推送能够吗?当然能够啦,不去调用 createPush()办法不就行了
  • 形象工厂最适宜什么场景?很显著,一系列相干对象的创立
  • 工厂办法模式是形象工厂的外围,相当于多个工厂办法被放到一个大工厂中生产一整套产品(蕴含周边)而不是一件独自的产品

下期看点

有没有化过妆?有没有搭配过衣服?化妆咱们要一层一层的化,衣服咱们要从里向外的穿?都没试过的话(海南程序员全年背心 + 短裤吗???那你也得穿内裤吧!!)…. 没关系,先带你理解下 装璜者模式

各自媒体平台均可搜寻【硬核项目经理】

退出移动版