设计模式之简单工厂模式(Simple Factory Pattern)

什么是简单工厂模式?

以下内容来自 ChatCPT 的回答:

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,其主要目的是将对象的创建过程封装在一个单独的类中,以便于在需要创建对象时,只需要通过向该类传递参数即可获取所需的对象,而不必直接实例化对象。

简单工厂模式通常包含一个工厂类,该类中包含一个静态方法,该方法接收不同的参数,并根据不同的参数来创建不同的对象。客户端只需要调用工厂类中的方法,并传递所需的参数即可创建相应的对象。

简单工厂模式可以有效地降低客户端与具体产品类之间的耦合度,提高系统的可扩展性和可维护性,同时也可以使客户端代码更加简洁和易于理解。

讲人话?

今天你上工厂干活,你需要跟这三个人配合才能完成任务:张三,李四,王六。

不使用简单工厂设计模式
  1. 第一件事需要张三跟你拧螺丝,你得自己去喊他,叫他过来跟你拧螺丝。
  2. 第二件事需要李四跟你搬原料,你得自己去喊他,叫他过来跟你搬原料。
  3. 第三件事需要王六跟你扫地板,你得自己去喊他,叫他过来跟你扫地板。
使用了简单工厂设计模式

你昨天喊了半天,每干一件事情都要自己亲自去找人,费事不说,有时候还找不到人,还要看人脸色
今天你学聪明了,叫来了厂长,让他帮你叫人

  1. 第一件事需要张三跟你拧螺丝,你跟厂长说,厂长立马把张三叫过来,跟你一起拧螺丝。
  2. 第二件事需要李四跟你搬原料,你跟厂长说,厂长立马把李四叫过来,跟你一起搬原料。
  3. 第三件事需要王六跟你扫地板,你跟厂长说,厂长立马把王六叫过来,跟你一起扫地板。

这里的核心就是,你找到了靠山,厂长,需要什么资源,找他,需要什么人,找他,他就是工厂模式里面的那个工厂。

有什么用?

假设,你领导让你开发一个机票预定系统,机票来源有多家【去哪儿、携程、欣欣旅游】,客户可以根据自己的喜好,选择购买不同公司的机票。

接到这个需求,你二话不说,拿起键盘噼里啪啦狂敲,瞬间对接好了各家供应商的购票下单逻辑。

<?php

interface Flight
{
    /**
     * 买票了
     */
    public function buyTicket();
}

/**
 * 去哪儿网
 */
class QunarFlight implements Flight
{
    public function buyTicket()
    {
        echo '欢迎来到【去哪儿网】购买机票' . PHP_EOL;
        // 这里省略 210 行代码...
    }
}

/**
 * 携程
 */
class CtripFlight implements Flight
{
    public function buyTicket()
    {
        echo '欢迎来到【携程】购买机票' . PHP_EOL;
        // 这里省略 180 行代码...
    }
}

/**
 * 欣欣旅游
 */
class CncnFlight implements Flight
{
    public function buyTicket()
    {
        echo '欢迎来到【欣欣旅游】购买机票,这里购买机票折扣很大。' . PHP_EOL;
        // 这里省略 21 行代码...
    }
}

系统刷的一下子上线了,顾客来了,开始订票了。
老板乐开了花。

// 顾客A要了一张去哪儿的机票
$customerA = new QunarFlight();
$customerA->buyTicket();

// 顾客B要了一张携程的机票
$customerB = new CtripFlight();
$customerB->buyTicket();

// 顾客C要了一张欣欣旅游的机票
$customerC = new CncnFlight();
$customerD->buyTicket();

干的很不错,你们公司业务蒸蒸日上,又陆续对接了50家机票供应商。顾客需要什么我就给你 new 什么。:)

$customer1 = new Supplier1Flight();
$customer2 = new Supplier2Flight();
$customer3 = new Supplier3Flight();
$customer4 = new Supplier4Flight();
$customer5 = new Supplier5Flight();
$customer6 = new Supplier6Flight();
$customer7 = new Supplier7Flight();
$customer8 = new Supplier8Flight();
$customer9 = new Supplier9Flight();
...

今天你们公司新入职了个程序媛,她看到这段代码后,呆住了,震惊了,满脸惊讶坐在那里盯着屏幕一动不动,陷入沉思。
你问她:怎么样,代码写得太棒了惊艳到你了是吗?公司的业务全靠它起来的。
妹子回过神来,说:你有没有听说过简单工厂模式
你瞬间炸了?啥?工厂模式?还是简单的??那玩意有啥用?别整那些有的没的,好好看代码,等下安排任务给你了。
要强的你,下班后,偷偷网上google了一下,看了180篇相关的文章,默默留下无知的眼泪,拿起键盘又一阵狂敲。

/**
 * 我是机票工厂,你要哪家供应商的机票,跟我说名字就行,我拿给你
 */
class FlightFactory
{
    public static function getFlightSupplier(string $supplierName)
    {
        switch ($supplierName) {
            case 'qunar':
                return new QunarFlight();
            case 'ctrip':
                return new CtripFlight();
            case 'cncn':
                return new CncnFlight();
            default:
                throw new \http\Exception\InvalidArgumentException('你选择供应商我们暂时还没接入,请你先选择其他供应商下单,我们将尽快接入');
        }
    }
}

// 顾客A要欣欣旅游的机票
$customerA = FlightFactory::getFlightSupplier('cncn');
// 顾客B要携程的票
$customerB = FlightFactory::getFlightSupplier('qunar');
// 顾客C要去哪儿的票
$customerC = FlightFactory::getFlightSupplier('ctrip');
// 顾客D要途牛的票
$customerD = FlightFactory::getFlightSupplier('tuniu');

Laravel源码中,有没有用到该设计模式的地方?

这里使用的是 Laravel 8.83.27
具体使用:根据配置信息返回不同的数据库连接对象

<?php

namespace Illuminate\Database\Connectors;

use Illuminate\Contracts\Container\Container;
use Illuminate\Database\Connection;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\PostgresConnection;
use Illuminate\Database\SQLiteConnection;
use Illuminate\Database\SqlServerConnection;
use Illuminate\Support\Arr;
use InvalidArgumentException;
use PDOException;

class ConnectionFactory
{
    /**
     * Create a connector instance based on the configuration.
     *
     * @param  array  $config
     * @return \Illuminate\Database\Connectors\ConnectorInterface
     *
     * @throws \InvalidArgumentException
     */
    public function createConnector(array $config)
    {
        if (! isset($config['driver'])) {
            throw new InvalidArgumentException('A driver must be specified.');
        }

        if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
            return $this->container->make($key);
        }

        switch ($config['driver']) {
            case 'mysql':
                return new MySqlConnector;
            case 'pgsql':
                return new PostgresConnector;
            case 'sqlite':
                return new SQLiteConnector;
            case 'sqlsrv':
                return new SqlServerConnector;
        }

        throw new InvalidArgumentException("Unsupported driver [{$config['driver']}].");
    }
    
    /**
     * Create a new connection instance.
     *
     * @param  string  $driver
     * @param  \PDO|\Closure  $connection
     * @param  string  $database
     * @param  string  $prefix
     * @param  array  $config
     * @return \Illuminate\Database\Connection
     *
     * @throws \InvalidArgumentException
     */
    protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
    {
        if ($resolver = Connection::getResolver($driver)) {
            return $resolver($connection, $database, $prefix, $config);
        }

        switch ($driver) {
            case 'mysql':
                return new MySqlConnection($connection, $database, $prefix, $config);
            case 'pgsql':
                return new PostgresConnection($connection, $database, $prefix, $config);
            case 'sqlite':
                return new SQLiteConnection($connection, $database, $prefix, $config);
            case 'sqlsrv':
                return new SqlServerConnection($connection, $database, $prefix, $config);
        }

        throw new InvalidArgumentException("Unsupported driver [{$driver}].");
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值