设计模式之工厂模式

2020年11月23日 阅读数:6
这篇文章主要向大家介绍设计模式之工厂模式,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

关于设计模式这一块,我的以为仍是挺重要的。由于这个关乎到代码的优雅程度。php

今天不讲设计模式六大原则,就单纯的来讲说我对工厂模式的理解,用最通俗易懂的天然语言,讲述一下工厂模式的原理。设计模式

定义学习

什么是工厂模式?就是一种建立型的设计模式。这么说可能有些晦涩,用通俗易懂的话来讲,就是按照一种相似于工厂生产商品的方式来对类进行实例化,而不是用到了就new一个。spa

简单工厂模式设计

如今有一个客户,肚子饿了,想吃方便面。他如今脑子里这有一个念头:快点吃到方便面,他根本就不想了解方便面究竟是怎么生产出来的(客户端与实现的解耦)。这个时候若是有一个卖方便面的小店(工厂)就行了,客户只须要看一下店里有哪些方便面。而后挑选一包就行了。code

优势:对象

白话:客户不须要知道怎么生产方便面,就能够吃到想要的方便面,甚至能挑选到本身想要的那个牌子的方便面。blog

书面:客户端和具体实现的解耦。接口

缺点:开发

白话:这个小店为了应对愈来愈多的客户需求,进货的时候进了100多种品牌的方便面,味道各不同,描述七老比较困难。吃的方法也不同,有一些是水煮的,有一些是干吃的,有一些是干拌的。所以老板本身也常常记错,更别说客户问的时候听得一头雾水了。客户挑了半天,可能并不能挑到本身心满意足的产品。

书面:随着数据量的增大,工厂类会变得臃肿。逻辑和实现混杂在一块儿,使得工厂类的内部构造变得难以理解和维护,很是不利于后期的拓展。对于客户端来讲,须要知道工厂的内部实现,增长了大量的学习成本,增长了客户端的复杂度。

实现:

首先咱们须要定义一个方便面的接口,每包方便面均可以吃:

//noodles.php
interface Noodles{
    public function eat();  
}

而后咱们写两个实现类,分别表明康师傅生产的方便面,和统一辈子产的方便面:

//kangNoodles.php
class KangNoodles implements Noodles{
    public function eat(){
        echo '吃一包美味的康师傅红烧牛肉面';
    }  
}
//Tongyi.php
class TongyiNoodles implements Noodles{
    public function eat(){
        echo '吃一包美味的统一红烧牛肉面';
    }  
}

而后咱们生成一个简单工厂:

//NoodlesFactory.php
class NoodlesFactory{
    public function createNoodles($brand){
        switch($brand){
            case 'kang':
                return new KangNoodles();
            case 'tongyi':
                return new TongyiNoodles();        
        }
    }    
}

生成客户端:

//SimpleFactoryDemo.php
class SimpleFactoryDemo{    
    public function setNoodles($brand){
        $noodles = (new NoodlesFactory())->createNoodles($brand);
        $noodles->eat();
    } 
}

工厂模式

仍是上述场景,客户肚子饿了想吃方便面。如今咱们创建一个康师傅工厂,专门生产(售卖)康师傅红烧牛肉面,再创建一个生产(售卖)统一红烧牛肉面的工厂,等等,在理想的条件下,咱们甚至能够创建起100个品牌的方便面加工工厂,客户想吃哪个牌子,直接去对应的工厂(商店)进行购买就好了。

优势:

相对于简单工厂模式,工厂模式的每个工厂都作本身的事,避免创建起一个庞大而又臃肿的工厂。有利于代码的扩展和维护。

缺点:

每增长一个产品,相应的也要增长一个子工厂,加大了额外的开发量(我的以为这一点能够接受,不算什么太大的缺点)

实现:

首先咱们须要定义一个方便面的接口

 

//noodles.php
interface Noodles{
    public function eat();  
}

 

而后咱们写两个实现类,分别表明生产康师傅生产的方便面,和统一辈子产的方便面这种商品:

//kangNoodles.php
class KangNoodles implements Noodles{
    public function eat(){
        echo '吃一包美味的康师傅红烧牛肉面';
    }  
}
//Tongyi.php
class TongyiNoodles implements Noodles{
    public function eat(){
        echo '吃一包美味的统一红烧牛肉面';
    }  
}

 

 

而后,生成一个工厂接口:

//NoodlesFactory.php
interface NoodlesFactory{
    public function createNoodles();
}

咱们生成两个对应的工厂:

 

//KangNoodlesFactory.php
class KangNoodlesFactory implements NoodlesFactory{
     public function createNoodles(){
         return new KangNoodles();  
    }  
}
//TongyiNoodlesFactory.php
class TongyiNoodlesFactory implements NoodlesFactory{
     public function createNoodles(){
         return new TongyiNoodles();  
    }  
}

 

生成客户端:

//FactoryDemo.php
class FactoryDemo{    
    public function kangFunc(){
        $noodles = (new KangNoodlesFactory())->createNoodles();
        $noodles->eat();  
    } 

    public function TongyiFunc(){
        $noodles = (new TongyiNoodlesFactory())->createNoodles();
        $noodles->eat();  
    } 
    
}

抽象工厂模式

仍是上述场景,随着物质条件的提高,客户提出,要在吃泡面的时候加一分榨菜,造成一个套餐。这个时候怎么办?

咱们能够把泡面和榨菜想象成一个“套餐”,统一交给一家工厂(商店)去帮忙搞定。市场上因而新推出一条这样的套餐:泡面——榨菜。因而各个厂家纷纷效仿,推出自家工厂的“套餐”。客户只须要到对应的工厂直接下单套餐就好了,无需其余操做。

优势:

拥有工厂模式的优势。

拥有产品族的概念,这一系列的产品源于同一厂家,易于管理约束。保证客户只使用同一家工厂的产品。

一个具体的工厂实现表明的是一个产品族,切换产品族只须要切换一下具体工厂

缺点:

若是要新增长一个产品,好比说套餐中要加入一款饮料。那么全部的工厂都要去遵循这个规定,去研发出一款自家的饮料,比较麻烦。

实现:

首先咱们须要定义一个方便面的接口

//noodles.php
interface Noodles{
    public function eat();  
}

而后咱们写两个实现类,分别表明生产康师傅生产的方便面,和统一辈子产的方便面这种商品:

//kangNoodles.php
class KangNoodles implements Noodles{
    public function eat(){
        echo '吃一包美味的康师傅红烧牛肉面';
    }  
}
//Tongyi.php
class TongyiNoodles implements Noodles{
    public function eat(){
        echo '吃一包美味的统一红烧牛肉面';
    }  
}

咱们再写一个榨菜的接口:

//Mustard.php
interface Mustard{
    public functioneat();
}

再写两个榨菜的实现类:

//kangMusterd.php
class kangMusterd implements Musterd{
    public function eat(){
        echo '吃一包美味的康师傅榨菜';
    }  
}
//Tongyi.php
class TongyiMusterd implements Musterd{
    public function eat(){
        echo '吃一包美味的统一榨菜';
    }  
}

写一个抽象工厂,包含多个产品:

//AbstractFactory.php
abstract AbstractFactory(){
     abstract public function createNoodle();
     abstract public function createMusterd();
}

生成两个工厂类:

//KangFactory.php
class KangFactory extends AbstractFactory{
    public function createNoodles(){
        return new KangNoodles();
    }

    public function createMusterd(){
        return new KangMusterd();
    }
}
//TongyiFactory.php
class TongyiFactory extends AbstractFactory{
    public function createNoodles(){
        return new TongyiNoodles();
    }

    public function createMusterd(){
        return new TongyiMusterd();
    }
}

客户端:

//AbstractFactoryDemo.php
class AbstractFactoryDemo{
    public function eatKangTaocan(){
        $kangFactory = new KangFactory();
        $noodles = $kangFactory->createNoodles();
        $musterd = $kangFactory->createMusterd();
        $noodles->eat();
        $musterd->eat();
    }  
    public function eatTongyiTaocan(){
        $TongyiFactory = new TongyiFactory();
        $noodles = $TongyiFactory->createNoodles();
        $musterd = $TongyiFactory->createMusterd();
        $noodles->eat();
     $musterd->eat();

    }   
}  

总结:

后两种工厂模式,其实就是把建立对象的那个行为抽象出来了,作到了低耦合。