极简设计模式-工厂模式

PHP技术
395
0
0
2022-07-22

工厂模式 Factory Pattern

简述

工厂模式分三种类型。

1. 简单工厂模式。

2. 工厂方法模式。

3. 抽象工厂模式。

设计的原则和思想

把对象的创建封装在工厂类中,解耦对象的创建和使用。

产品等级结构和产品族

产品等级结构 :

继承结构,就是同类。例如,华为手机,小米手机,魅族手机,这些都是具体实现类,抽象类是手机。

产品族 :

是同一个牌子的产品,都是由同一个工厂生产的。例如,华为手机,华为平板,华为电脑,这些构成了一个华为的产品族。

简单工厂模式 - Simple Factory Pattern

定义

1. 一个工厂类,根据参数的不同返回不同类的实例。
2. 简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法(Static Factory Method)模式。

一句话概括设计模式

一个静态方法返回产品对象。

结构中包含的角色

1. Factory(工厂角色)
2. Product(抽象产品角色)
3. ConcreteProduct(具体产品角色)

最小可表达代码

// 产品
abstract class Product {}
class ConcreteProductA extends Product {}
class ConcreteProductOther extends Product {}

// 简单工厂
class SimpleFactory {
    public static getProduct($param) : Product
    {  
        if ("A" == $param) {
            return new ConcreteProductA();  
        }  

        return new ConcreteProductOther();
    }  
}

优点

  1. 根据参数就可以创建产品,不需要知道产品的具体实现。
  2. 实现对象的创建和使用分离。

缺点

  1. 随着时间的推移,产品的具体类逐渐增多,工厂的逻辑会逐渐复杂,不利于系统的扩展和维护。
  2. 增加产品等级结构,需要增加对应的工厂类,增加产品族也必须修改工厂类。

何时使用

  1. 根据不同的条件生成不同的对象,并且创建的对象比较少,例如框架中配置的驱动。
  2. 一个对象的创建比较复杂。

实际应用场景

  1. PDO中的数据库驱动。Mysql,DB2,还是Oracle。

工厂方法模式 - Factory Method Pattern

定义

  1. 一个用于创建对象的接口,让子类决定将哪一个类实例化(一个工厂实例化一个产品类)。
  2. 工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。

一句话概括设计模式

不同的工厂返回不同的产品对象。

结构中包含的角色

  1. Product(抽象产品)
  2. ConcreteProduct(具体产品)
  3. Factory(抽象工厂)
  4. ConcreteFactory(具体工厂)

最小可表达代码

// 产品
interface Product {}
class ConcreteProductA implements Product {}
class ConcreteProductOther implements Product {}

// 工厂
interface Factory {
    public function createProduct() : Product;
}
class ConcreteFactoryA implements Factory {  
    public public createProduct() : Product
    {  
        return new ConcreteProductA();
    }     
}
class ConcreteFactoryOther implements Factory {  
    public public createProduct() : Product
    {  
        return new ConcreteProductOther();
    }     
}

优点

  1. 客户端只要知道产品对应的工厂即可,不需要知道具体产品的类名。
  2. 新增产品只需要添加一个具体工厂和具体产品就可以了,可扩展性非常好。

缺点

  1. 新增产品会导致系统中存在大量的工厂类。
  2. 使用了抽象,并且实现时可能还会用到反射或者IOC,增加了系统的复杂度。

何时使用

  1. 工厂方法模式实际上是多个简单工厂模式的集合。所以,当简单工厂里面的产品过多时,可以使用工厂方法模式解耦。
  2. 运行时动态决定所需的类。可将具体工厂类的类名存储在配置文件,运行时通过反射实例化。虽然简单工厂也可以做到,但是违反了开闭原则。

实际应用场景

  1. 商城的商品有精选商品,收藏的商品,销售最高的商品,每类商品都有所差异,可以使用工厂方法模式设计。
  2. 框架中,通过配置实例化类。例如laravl中,通过config/cache配置选择缓存(redis 或 memcached)驱动。

抽象工厂模式-Abstract Factory Pattern

定义

提供一个创建一系列相关或相互依赖对象的接口(每个工厂负责创建整个产品族),而无须指定它们具体的类。

一句话概括设计模式

一个工厂有不同的方法,不同的方法返回不同的产品对象。简单就是一个工厂返回一系列产品。

结构中包含的角色

  1. AbstractFactory(抽象工厂)
  2. ConcreteFactory(具体工厂)
  3. AbstractProduct(抽象产品)
  4. ConcreteProduct(具体产品)

最小可表达代码

// 手机产品
interface Phone {}  
class HuaWeiPhone implements Phone {}   
class XiaoMiPhone implements Phone {}  

// 笔记本产品
interface NoteBook {}  
class HuaWeiNoteBook implements NoteBook {}   
class XiaoMiNoteBook implements NoteBook {}  

// 工厂
interface Factory {  
    public function createPhone() : Phone;  
    public function createNoteBook() : NoteBook; 
}  
// 华为工厂
class HuaWeiFactory implements Factory {  
    public function createPhone() {  
        return new HuaWeiPhone();  
    }  
    public function createNoteBook() {  
        return new HuaWeiNoteBook();  
    }
} 
// 小米工厂
class XiaoMiFactory implements Factory {  
    public function createPhone()
    {  
        return new XiaoMiPhone();  
    }  
    public function createNoteBook() {  
        return new XiaoMiNoteBook();  
    }  
}

优点

  1. 增加新的产品族(新增具体工厂和具体产品)无须修改已有系统,符合开闭原则。

缺点

  1. 增加新的产品等级结构(所有具体工厂都要修改,新增抽象产品和具体产品),需要对原有系统进行较大的修改。

何时使用

  1. 抽象工厂模式实际上是多个工厂方法模式的集合。所以,当工厂方法模式里面存在多个产品等级结构时,可以使用抽象工厂模式。
  2. 同一个产品族的产品,它们之间打包在一起使用。

实际应用场景

  1. 同一个产品族的产品。qq皮肤,窗口和菜单都属于同一个主题。
  2. 不同操作系统的程序。按钮与文本框都是属于某一操作系统。