工厂模式 Factory Pattern
简述
工厂模式分三种类型。
    1. 简单工厂模式。
    2. 工厂方法模式。
    3. 抽象工厂模式。
设计的原则和思想
- 解耦了对象的创建和使用。
 - 不变部分是使用,变化部分是创建。
 - 核心思想是对象的创建封装在工厂类中。
 
产品等级结构和产品族
产品等级结构 : 
    继承结构,就是同类。例如,华为手机,小米手机,魅族手机,这些都是具体实现类,抽象类是手机。  
产品族 : 
    是同一个牌子的产品,都是由同一个工厂生产的。例如,华为手机,华为平板,华为电脑,这些构成了一个华为的产品族。
简单工厂模式 - Simple Factory Pattern
定义
- 一个工厂类,根据参数的不同返回不同类的实例。
 - 简单工厂模式中用于创建实例的方法是静态(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();
    }  
}
优点
- 根据参数就可以创建产品,不需要知道产品的具体实现。
 - 实现对象的创建和使用分离。
 
缺点
- 随着时间的推移,产品的具体类逐渐增多,工厂的逻辑会逐渐复杂,不利于系统的扩展和维护。
 - 增加产品等级结构,需要增加对应的工厂类,增加产品族也必须修改工厂类。
 
何时使用
- 根据不同的条件生成不同的对象,并且创建的对象比较少,例如框架中配置的驱动。
 - 一个对象的创建比较复杂。
 
实际应用场景
- PDO中的数据库驱动。Mysql,DB2,还是Oracle。
 
工厂方法模式 - Factory Method Pattern
定义
- 一个用于创建对象的接口,让子类决定将哪一个类实例化(一个工厂实例化一个产品类)。
 - 工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。
 
一句话概括设计模式
不同的工厂返回不同的产品对象。
结构中包含的角色
- Product(抽象产品)
 - ConcreteProduct(具体产品)
 - Factory(抽象工厂)
 - 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();
    }     
}
优点
- 客户端只要知道产品对应的工厂即可,不需要知道具体产品的类名。
 - 新增产品只需要添加一个具体工厂和具体产品就可以了,可扩展性非常好。
 
缺点
- 新增产品会导致系统中存在大量的工厂类。
 - 使用了抽象,并且实现时可能还会用到反射或者IOC,增加了系统的复杂度。
 
何时使用
- 工厂方法模式实际上是多个简单工厂模式的集合。所以,当简单工厂里面的产品过多时,可以使用工厂方法模式解耦。
 - 运行时动态决定所需的类。可将具体工厂类的类名存储在配置文件,运行时通过反射实例化。虽然简单工厂也可以做到,但是违反了开闭原则。
 
实际应用场景
- 商城的商品有精选商品,收藏的商品,销售最高的商品,每类商品都有所差异,可以使用工厂方法模式设计。
 - 框架中,通过配置实例化类。例如laravel中,通过config/cache配置选择缓存(redis 或 memcached)驱动。
 
抽象工厂模式-Abstract Factory Pattern
定义
提供一个创建一系列相关或相互依赖对象的接口(每个工厂负责创建整个产品族),而无须指定它们具体的类。
一句话概括设计模式
一个工厂有不同的方法,不同的方法返回不同的产品对象。简单就是一个工厂返回一系列产品。
结构中包含的角色
- AbstractFactory(抽象工厂)
 - ConcreteFactory(具体工厂)
 - AbstractProduct(抽象产品)
 - 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();  
    }  
}
优点
- 增加新的产品族(新增具体工厂和具体产品)无须修改已有系统,符合开闭原则。
 
缺点
- 增加新的产品等级结构(所有具体工厂都要修改,新增抽象产品和具体产品),需要对原有系统进行较大的修改。
 
何时使用
- 抽象工厂模式实际上是多个工厂方法模式的集合。所以,当工厂方法模式里面存在多个产品等级结构时,可以使用抽象工厂模式。
 - 同一个产品族的产品,它们之间打包在一起使用。
 
实际应用场景
- 同一个产品族的产品。qq皮肤,窗口和菜单都属于同一个主题。
 - 不同操作系统的程序。按钮与文本框都是属于某一操作系统。
 
          
99+种软件模式
                    
                    
            
            
                关于 LearnKu
              
                    
                    
                    
 
推荐文章: