设计模式---工厂模式

前言:(这是废话)
最近小编忙于毕设,在写小程序,在写laravel后端和小程序前端的时候突然觉得这样搬砖真的好无聊,每天写来写去都是一些固定的套路,小编一度认为学习php的意义在哪里,难道以后就要这样一直搬砖了嘛。小编突然意识到自己可能学的还是不够深刻。想一想自己会一些什么,php的基础似乎并没有很牢固,之前忙于学习别人的框架,大多数都会用了,但去也曾深入的尝试了解框架深层的东西,但往往要花费很多时间。总的来说之前忙于追求框架而忽略了php一些基础的东西,而框架也只学了个中等,一些内在的东西又看不懂,所以小编常常有种自己好菜的感觉。所以小编想说的是基础真的很重要,还有编程思想,这些才是php进阶的保障。
此博客用于个人学习笔记,还请大神有错纠正,不喜勿喷
一.为什么要使用工厂模式
什么是工厂模式呢,很多地方有这样说道:工厂模式就是为了把对象的创建与使用的过程分开或者是将“类实例化的操作”与“使用对象的操作”分开。那我们怎么来理解这一句话呢。举个简单的例子。我们像调用ProductA类里面的show方法,我们一般的的做法是下面这样
在这里插入图片描述
这就是我们平时用new来实例化对象进而使用类中的方法。这样子的确没有什么问题。
但是如果一个类的构造函数很复杂,需要用到其他的类,像这样

class size
{
    protected $size;
    public function __construct($size)
    {
        $this->size=$size;
    }
    public function size(){
        echo   $this->size;
    }
}
class name
{
    protected $name;
    public function __construct($name)
    {
        $this->name=$name;
    }
    public function name(){
        echo   $this->name;
    }
}
class ProductA
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show(){
     echo $this->name->name();
     echo $this->size->size();
 }
}
$name=new name('产品A');
$size=new size('50X50');
$product=new ProductA($name,$size);
$product->show();

这里面我们可以看到ProductA类的构造需要用到name和size类,也许这样这看起来有人说不是很复杂可以直接new。但是如ProductA类的构造函数需要很多个其他类的参数, p r o d u c t = n e w P r o d u c t A ( product=new ProductA( product=newProductA(name, s i z e , size, size,color……)
那我每new一个ProductA类就要new很多构造函数用到的其他类,一但代码中用的需要实例化很多ProductA类,那么此时就会有很多重复的代码,假设我们上面一样写了很多的代码,有一天发现ProductA类的构造函数的参数需要修改增或删除一个参数,或者修改ProductA类的名字为ProductB。那么我们就要一个个去修改我们new ProductA类的地方。这显然不现实,很费时间。那么造成这样的原因就是new 把对象的创建和使用的过程放在了一起,每次使用一个类时我们都要去创建一个类对象,耦合度高。此外我们还可以看到每一次new我们都要知道ProductA的构造函数有哪些参数,即对象的创建逻辑与过程。如果
对象的创建逻辑与过程很复杂很繁琐,那么我们每一次都要去理一遍显然不合理,也很麻烦。
一次我们使用工厂模式。
通过上面的的例子我们可以总结出来使用工厂模式的好处就是:

  1. 解耦,将“类实例化的操作”与“使用对象的操作”分开。
  2. 降低代码重复
  3. 然使用者不需要知道类对象创建的逻辑,直接使用其中方法就好了。

二.分类

1.简单工厂
简单工厂又叫做静态方法模式。工厂类中定义了静态方法用来创建产品类实例。使用的时候直接调用静态方法。

使用步骤
• 创建抽象产品类 & 定义具体产品的公共接口;
• 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
• 创建工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
• 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例

•	<?php

class size
{
    protected $size;
    public function __construct($size)
    {
        $this->size=$size;
    }
    public function size(){
        echo   $this->size;
    }
}
class name
{
    protected $name;
    public function __construct($name)
    {
        $this->name=$name;
    }
    public function name(){
        echo   $this->name;
    }
}

//具体产品的公共接口
interface Shoes{
 public function show();
}
//具体产品类
class ShoesA implements Shoes
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show()
    {
        // TODO: Implement show() method.
        echo $this->name->name();
        echo $this->size->size();
    }
}
class ShoesB implements Shoes
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show(){
        echo $this->name->name();
        echo $this->size->size();
    }
}
//工厂类

class  Factory {
     static function createshoes($name,$size,$class){

        if($class=="A"){
            $name1=new name($name);
            $size1=new size($size);
            return  new ShoesA($name1,$size1);
        }
        else if($class=='B'){
            $name1=new name($name);
            $size1=new size($size);
            return  new ShoesB($name1,$size1);
        }
    }
}
  Factory:: createshoes('鞋子A','50x50',"A")->show();

简单工厂的缺点:
将所有的产品即实例放到一个工厂中,一但这个工厂出错那么所有的产品都无法生产
因此为了克服这个确定我们产生了工厂方法模式。
二.工厂方法模式
工厂方法模式是将类的实例化延迟到工厂类的子类中完成,即由子类来决定应该实例化哪一个类,哪个产品由哪个工厂生产。

<?php

class size
{
    protected $size;
    public function __construct($size)
    {
        $this->size=$size;
    }
    public function size(){
        echo   $this->size;
    }
}
class name
{
    protected $name;
    public function __construct($name)
    {
        $this->name=$name;
    }
    public function name(){
        echo   $this->name;
    }
}

//具体产品的公共接口
interface Shoes{
 public function show();
}
//具体产品类
class ShoesA implements Shoes
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show()
    {
        // TODO: Implement show() method.
        echo $this->name->name();
        echo $this->size->size();
    }
}
class ShoesB implements Shoes
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show(){
        echo $this->name->name();
        echo $this->size->size();
    }
}
//工厂类
interface Factory {
     public function createshoes($name,$size);
}
class FactoryA implements  Factory {

    public function createshoes($name, $size)
    {
        // TODO: Implement create() method.
        $name1=new name($name);
        $size1=new size($size);
        return  new ShoesA($name1,$size1);

    }
}
class FactoryB implements  Factory {

    public function createshoes($name, $size)
    {
        // TODO: Implement create() method.
        $name1=new name($name);
        $size1=new size($size);
        return  new ShoesB($name1,$size1);

    }
}
  $factorya=new FactoryA();
$factorya->createshoes('鞋子A','50x50')->show();
$factoryb=new FactoryA();
$factoryb->createshoes('鞋子B','100x100')->show();

缺点:每个工厂只能创建一类产品

三.抽象工厂模式
从工厂方法模式中我们可以看到FactoryA,FactoryB只能生产不同品牌的鞋子要是我们想让它们生产汽车它们就没有办法了。因此我们使用工厂模式用于每个工厂可以创建多种类的产品

<?php

class size
{
    protected $size;
    public function __construct($size)
    {
        $this->size=$size;
    }
    public function size(){
        echo   $this->size;
    }
}
class name
{
    protected $name;
    public function __construct($name)
    {
        $this->name=$name;
    }
    public function name(){
        echo   $this->name;
    }
}

//具体产品的公共接口
interface Shoes{
 public function show();
}
//具体产品类
class ShoesA implements Shoes
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show()
    {
        // TODO: Implement show() method.
        echo $this->name->name();
        echo $this->size->size();
    }
}
class ShoesB implements Shoes
{
    protected $name,$size;
    public function __construct(name $name,size $size)
    {
        $this->name=$name;
        $this->size=$size;
    }
    public function show(){
        echo $this->name->name();
        echo $this->size->size();
    }
}
interface Car{
    public function show();
}
class CarA implements Car
{

    public function show()
    {
        echo"生产汽车A";
    }
}
class CarB implements Car
{
    public function show(){
        echo"生产汽车B";
    }
}
//工厂类
interface Factory {
     public function createshoes($name,$size);
    public function createcars();
}
class FactoryA implements  Factory {

    public function createshoes($name, $size)
    {
        // TODO: Implement create() method.
        $name1=new name($name);
        $size1=new size($size);
        return  new ShoesA($name1,$size1);

    }

    public function createcars()
    {
        // TODO: Implement createcars() method.
        return  new CarA();
    }
}
class FactoryB implements  Factory {

    public function createshoes($name, $size)
    {
        // TODO: Implement create() method.
        $name1=new name($name);
        $size1=new size($size);
        return  new ShoesB($name1,$size1);

    }

    public function createcars()
    {
        // TODO: Implement createcars() method.
        return  new CarB();
    }
}
  $factorya=new FactoryA();
$factorya->createshoes('鞋子A','50x50')->show();
$factorya->createcars()->show();
$factoryb=new FactoryA();
$factoryb->createshoes('鞋子B','100x100')->show();
$factoryb->createcars()->show();

后记:
最后这边再说一下什么是实例化对象。小编突然像想到这样一个问题我的第一反应是不就是new嘛。可是真让我说我竟以实语塞。后来仔细想想。这几个字要分开来想 s t u d e n t = n e w s t u d e n t ( ) ; 前 面 的 student =new student();前面的 student=newstudent(); student是我们的类对象而用new 关键字创建类对象的过程就是我们所说的实例化。
参考:
https://blog.csdn.net/fmyzc/article/details/79614944
https://www.jianshu.com/p/e55fbddc071c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值