设计模式——创建型/工厂模式(Factory Method)

问题:
1、什么是工厂模式
2、工厂模式是怎样的。
3、工厂模式有什么优点跟确定
4、工厂模式什么时候用到(应用场景)

1、什么是工厂模式

工厂模式包括简单工厂模式、工厂方法模式、抽象工厂模式这3种细分模式。
其实通俗来说:在编程的过程中,总会面临一些类的创建以及对象的创建,由于需求不断的变动,导致对象不断变化。
而工厂模式提供的是一种封装机制,将容易变动的对象封装起来,这样需求变动不影响之前的对象的变动。

2、简单工厂模式
定义:一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。(就是把产品的实现,分到子类中实现,通过接口来调用。静态工厂方法模式,提供一个工厂方法供客户端调用)。
简单工厂模式原理图

优点

1、 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
2、客户端无需知道所创建具体产品的类名,只需知道参数即可。
3、也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。

缺点

1、简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
2、使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
3、系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
4、简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。

应用场景

对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

第一步:创建了一个接口

<?php
header('Content-Type:text/html;charset=utf-8');
/**
 *简单工厂模式(静态工厂方法模式)
 */

/**
 * Interface people 支付(Interface定义为接口)
 */
interface  payment
{
    public function  pay();
}


第二步:创建实现接口的实体类。
/**
 * Class man 继承payment的淘宝类
 * 一个类通过关键字implements声明自己使用一个或者多个接口
 */
class taobao implements payment
{
    // 具体实现people的say方法
    public function pay()
    {
        echo '淘宝支付<br>';
    }
}

/**
 * Class women 继承payment的微信类
 */
class wechat implements payment
{
    // 具体实现people的say方法
    public function pay()
    {
        echo '微信支付<br>';
    }
}

第三步:创建一个工厂,生成基于给定信息的实体类的对象。

/**
 * Class SimpleFactoty 工厂类
 */
class SimpleFactoty
{
    // 简单工厂里的静态方法-用于创建淘宝对象
    static function createTaobao()
    {
        return new taobao();
    }

    // 简单工厂里的静态方法-用于创建微信对象
    static function createWechat()
    {
        return new wechat();
    }

}


第四步:调用实体类

/**
 * 具体调用
 */
$man = SimpleFactoty::createTaobao();
$man->pay();
$woman = SimpleFactoty::createWechat();
$woman->pay();

运行结果

淘宝支付
微信支付

工厂方法模式
定义一个用于创建对象的接口,让子类决定哪个类实例化。 他可以解决简单工厂模式中的封闭开放原则问题。如图

在这里插入图片描述

第一步:创建接口

<?php
header('Content-type:text/html;charset=utf-8');
/*
 *工厂方法模式
 */

/**
 * Interface people 人类
 */
interface  people
{
    public function  say();
}


第二步:创建实现接口的类

/**
 * Class man 继承people的男人类
 */
class man implements people
{
    // 实现people的say方法
    function say()
    {
        echo '我是男人-hi<br>';
    }
}

/**
 * Class women 继承people的女人类
 */
class women implements people
{
    // 实现people的say方法
    function say()
    {
        echo '我是女人-hi<br>';
    }
}


第三步:创建一个抽象接口类


/**
 * Interface createPeople 创建人物类
 * 注意:与上面简单工厂模式对比。这里本质区别在于,此处是将对象的创建抽象成一个接口。
 */
interface  createPeople
{
    public function create();

}

第四步:工厂类继承抽象类,实现实体类

/**
 * Class FactoryMan 继承createPeople的工厂类-用于实例化男人类
 */
class FactoryMan implements createPeople
{
    // 创建男人对象(实例化男人类)
    public function create()
    {
        return new man();
    }
}

/**
 * Class FactoryMan 继承createPeople的工厂类-用于实例化女人类
 */
class FactoryWomen implements createPeople
{
    // 创建女人对象(实例化女人类)
    function create()
    {
        return new women();
    }
}

第五步:调用方法

/**
 * Class Client 操作具体类
 */
class  Client
{
    // 具体生产对象并执行对象方法测试
    public function test() {
        $factory = new FactoryMan();
        $man = $factory->create();
        $man->say();

        $factory = new FactoryWomen();
        $man = $factory->create();
        $man->say();
    }
}

// 执行
$demo = new Client;
$demo->test();

运行结果

我是男人-hi
我是女人-hi

抽象工厂模式
提供一个创建一系列相关或相互依赖对象的接口。注意:这里和工厂方法的区别是:一系列(多个),而工厂方法只有一个。

<?php
header('Content-type:text/html;charset=utf-8');
/*
 * 抽象工厂模式
 */

/**
 * Interface people 人类
 */
interface  people
{
    public function  say();
}

/**
 * Class OneMan 第一个男人类-继承people
 */
class OneMan implements people
{
    // 实现people的say方法
    public function say()
    {
        echo '男1:我喜欢你<br>';
    }
}

/**
 * Class TwoMan 第二个男人类-继承people
 */
class TwoMan implements people{
    // 实现people的say方法
    public function say()
    {
        echo '男2:我看上你了<br>';
    }
}

/**
 * Class OneWomen 第一个女人类-继承people
 */
class OneWomen implements people {
    // 实现people的say方法
    public function say()
    {
        echo '女1:我不喜欢你<br>';
    }
}

/**
 * Class TwoWomen 第二个女人类-继承people
 */
class TwoWomen implements people {
    // 实现people的say方法
    public function say()
    {
        echo '女2:滚一边玩去<br>';
    }
}

/**
 * Interface createPeople 创建对象类
 * 注意:这里将对象的创建抽象成了一个接口。
 */
interface  createPeople
{
    // 创建第一个
    public function createOne();
    // 创建第二个
    public function createTwo();

}

/**
 * Class FactoryMan 用于创建男人对象的工厂类-继承createPeople
 */
class FactoryMan implements createPeople
{
    // 创建第一个男人
    public function createOne()
    {
        return new OneMan();
    }

    // 创建第二个男人
    public function createTwo()
    {
        return new TwoMan();
    }
}

/**
 * Class FactoryWomen 用于创建女人对象的工厂类-继承createPeople
 */
class FactoryWomen implements createPeople
{
    // 创建第一个女人
    public function createOne()
    {
        return new OneWomen();
    }

    // 创建第二个女人
    public function createTwo()
    {
        return new TwoWomen();
    }
}

/**
 * Class Client 执行测试类
 */
class  Client {

    // 具体生成对象和执行方法
    public function test() {
        // 男人
        $factory = new FactoryMan();
        $man = $factory->createOne();
        $man->say();

        $man = $factory->createTwo();
        $man->say();

        // 女人
        $factory = new FactoryWomen();
        $man = $factory->createOne();
        $man->say();

        $man = $factory->createTwo();
        $man->say();

    }
}

// 执行
$demo = new Client;
$demo->test();

运行结果

1:我喜欢你
男2:我看上你了
女1:我不喜欢你
女2:滚一边玩去

总结

区别
简单工厂模式(静态方法工厂模式) : 用来生产同一等级结构中的任意产品。(不能增加新的产品)
工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
抽象工厂 :用来生产不同产品种类的全部产品。(不能增加新的产品,支持增加产品种类)

适用范围
简单工厂模式:

  1. 工厂类负责创建的对象较少,操作时只需知道传入工厂类的参数即可,对于如何创建对象过程不用关心。

工厂方法模式:

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

抽象工厂模式:

  1. 满足以下条件时,可以考虑使用抽象工厂模式
  2. 系统不依赖于产品类实例如何被创建,组合和表达的细节。
  3. 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品
  4. 同属于同一个产品族是在一起使用的。这一约束必须在系统的设计中体现出来。
  5. 系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于实现。

应用场景

1、做支付接口的时候,未来可能对应不同的支付网关:支付宝、财付通、网银在线等。
2、方便未来扩展,设计成工厂模式。定一个专门生产网关接口的工厂,抽象出来,
3、做成接口形式,让所有的子类都要实现它的接口。
4、以后加一个支付方式,要使用哪一种支付方式,改变一下参数即可。
5、在为用户注册的时候,分为很多种角色的用户。
6、比如册用户,匿名用户、管理员用户等。完全使用可以使用工厂的思想来实现,
7、代码也容易维护,为每种角色可以生成操作的类等等。
8、系统对接多个不同类型的数据库,mysql,oracle,sqlserver

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值