【设计模式】抽象工厂模式
设计模式
1、定义
抽象工厂是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。抽象工厂定义了用于创建不同产品的接口,但将实际的创建工作留给了具体工厂类。每个工厂类型都对应一个特定的产品变体。
举个例子:
在本文提到的吉利和比亚迪都是汽车品牌。假设他们都可以自主生产汽车配件,那在组装汽车的时候只要固定在一个厂里调取配件,就不用担心用到其他厂商的配件,保证了整车都是用的一个品牌零部件。其中吉利和比亚迪就相当于两个具体的工厂,工厂可以生产很多的产品,如轮胎、车架、发动机等等。单把轮胎(系列产品中的抽象产品)拎出来看,轮胎就是一个系列,轮胎按照尺寸大小又分为18寸、20寸、22寸(这种具体尺寸的轮胎就是系列产品中的具体产品)等。
2、优缺点
- 优点
- 单一职责原则。可以将产品生成代码抽取到同一位置,使得代码易于维护。
- 开闭原则。向应用程序中引入新产品变体(特征)时,无需修改客户端代码。
- 可以避免客户端和具体产品代码的耦合。
- 可以确保同一工厂生成的产品相互匹配。
- 缺点
- 该模式需要向应用中引入众多接口和类,代码可能会更加复杂。
3、模式结构
-
抽象工厂(AbstractFactory):抽象工厂接口声明了一组能返回不同抽象产品的方法。
-
具体工厂(Concrete Factory):具体工厂可生成属于同一变体的系列产品。完成产品的创建。
-
系列产品中的抽象产品:系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。
-
系列产品中的具体产品:实现了抽象产品所定义的接口。
4、具体代码
抽象工厂(Abstract Factory):抽象工厂接口声明了一组能返回不同抽象产品的方法。
<?php namespace app\admin\service\design_mode\abstract_factory_method; interface AbstractFactory { /** * 汽车轮胎 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:20 */ public function tyre(); /** * 汽车车架 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:20 */ public function frame(); }
具体工厂(Concrete Factory):具体工厂可生成属于同一变体的系列产品。完成产品的创建。
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 比亚迪工厂 */ class BydFactory implements AbstractFactory { public function tyre(): Tyre { return new BydTyre(); } public function frame(): Frame { return new BydFrame(); } }
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 吉利工厂 */ class GeelyFactory implements AbstractFactory { public function tyre(): Tyre { return new GeelyTyre(); } public function frame(): Frame { return new GeelyFrame(); } }
系列产品中的抽象产品接口:系列产品中的特定产品必须有一个基础接口。所有产品变体都必须实现这个接口。
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 车架接口 */ interface Frame { /** * suv的车架 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:29 */ public function getSuvFrame(); /** * 轿车的车架 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:29 */ public function getSedanFrame(); }
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 轮胎接口 */ interface Tyre { /** * 18寸轮胎 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:31 */ public function get18Tyre(); /** * 20寸轮胎 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:31 */ public function get20Tyre(); /** * 22寸轮胎 * @return mixed * @Author: fengzi * @Date: 2024/3/14 15:31 */ public function get22Tyre(); }
系列产品中的具体产品:实现了抽象产品所定义的接口。
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 比亚迪车架 */ class BydFrame implements Frame { public function getSuvFrame() { echo "比亚迪SUV车架".PHP_EOL; } public function getSedanFrame() { echo "比亚迪轿车车架".PHP_EOL; } }
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 比亚迪造轮胎 */ class BydTyre implements Tyre { public function get18Tyre() { echo "比亚迪18寸轮胎".PHP_EOL; } public function get20Tyre() { echo "比亚迪20寸轮胎".PHP_EOL; } public function get22Tyre() { echo "比亚迪22寸轮胎".PHP_EOL; } }
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 吉利车架 */ class GeelyFrame implements Frame { public function getSuvFrame() { echo "吉利SUV车架".PHP_EOL; } public function getSedanFrame() { echo "吉利轿车车架".PHP_EOL; } }
<?php namespace app\admin\service\design_mode\abstract_factory_method; /** * 吉利轮胎 */ class GeelyTyre implements Tyre { public function get18Tyre() { echo "吉利18寸轮胎".PHP_EOL; } public function get20Tyre() { echo "吉利20寸轮胎".PHP_EOL; } public function get22Tyre() { echo "吉利22寸轮胎".PHP_EOL; } }
客户端调用代码
<?php namespace app\admin\controller\design_mode; use app\admin\service\design_mode\abstract_factory_method\BydFactory; use app\admin\service\design_mode\abstract_factory_method\GeelyFactory; /** * 抽象工厂模式 */ class AbstractFactoryMethodController { /** * 调用抽象工厂模式 * @return void * @Author: fengzi * @Date: 2024/3/14 15:39 */ public function index() { //比亚迪造车 $factory = new BydFactory(); $tyre = $factory->tyre(); $frame = $factory->frame(); $tyre->get18Tyre(); $frame->getSedanFrame(); echo '---------------'.PHP_EOL; $tyre->get22Tyre(); $frame->getSuvFrame(); echo '==========================='.PHP_EOL; //吉利造车 $factory = new GeelyFactory(); $tyre = $factory->tyre(); $frame = $factory->frame(); $tyre->get18Tyre(); $frame->getSedanFrame(); echo '---------------'.PHP_EOL; $tyre->get22Tyre(); $frame->getSuvFrame(); } }
客户端调用结果展示:
本文来自博客园,作者:疯子丶pony,转载请注明原文链接:https://www.cnblogs.com/mklblog/p/18034726