设计模式之工厂模式

详细内容请移步至语雀文档:点击跳转

一、何为工厂模式?

      工厂模式属于创建型设计模式,按实际业务场景划分,工厂模式共有 3 种实现方式,分别是简单工厂模式、工厂方法模式和抽象工厂模式。工厂模式用于定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。工厂模式满足了创建型模式中所要求的“创建与使用相分离”的特点。

      我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。

1.1 简单工厂模式

1.1.1  简单工厂模式的定义

      在工厂模式中,如果要创建的产品不多,只需要一个工厂类就可以完成,我们称其为“简单工厂模式”。
      提供一个创建对象实例的功能,而无须关心其具体的实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。简单工厂就是不能让模块外部知道模块内部的具体实现,但是模块内部还是可以知道实现类的,而且创建接口是需要知道具体的实现类的。所以,干脆在模块内部新建一个类,在这个类里面来创建接口,然后把创建的接口返回给具体调用者,这样,外部应用就只需根据这个类来获取相应的接口对象,然后就可以操作接口定义的方法了。把这样的对象就称作简单工厂,就叫它Factory。
      使用简单工厂的时候,通常不用创建简单工厂类实例,没有创建实例的必要。因此可以把简单那工厂类实现成一个工具类,直接使用静态方法即可。也就是说简单工厂的方法通常是静态的,所以也被称为静态工厂方法模式。如果要防止客户端无谓地创造简单工厂实例,还可以把简单工厂的构造方法私有化。简单工厂模式每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度,违背了“开闭原则”。
      一个简单工厂可以包含很多用来构造东西的方法,这些方法可以创建不同的接口、抽象类或者类实例。一个简单工厂理论上可以构造任何东西,所以又称之为“万能工厂”。
     虽然从理论上讲,简单工厂什么都能创建,但对于简单工厂可创建对象的范围,通常不要太大,建议控制在一个独立的组件级别或者一个模块级别,也就是一个组件或模块简单工厂。否则这个简单工厂类会职责不明,有点大杂烩的感觉。

1.1.2  简单工厂模式的优缺点

(1)优点:

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

(2)缺点:

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

1.1.3  简单工厂模式的应用场景

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

1.1.4  简单工厂模式的结构和说明

 简单工厂模式的主要角色如下:

  • 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
  • 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
  • 具体产品(ConcreteProduct):是简单工厂模式的创建目标。

简单工厂模式结构图如下图所示:

1.1.4  简单工厂模式的实现

//抽象产品
public interface Product {
    void show();
 }
 //具体产品:ProductA
public class ConcreteProduct1 implements Product {
   public void show() {
       System.out.println("具体产品1显示...");
   }
}
public class SimpleFactory {
    public static Product makeProduct(int kind) {
        switch (kind) {
            case 0:  return new ConcreteProduct1();
            case 1:  return new ConcreteProduct2();
            default: break;
            }
            return null;
    }
}
public class Customer {
  public static void main(String[] args){
      Product product01 = SimpleFactory.makeProduct(0);
  }
}
public class Customer {
  public static void main(String[] args){
      Product product01 = SimpleFactory.makeProduct(0);
  }
}

2.1 工厂方法模式

1.1.1  工厂方法模式的定义

    现实生活中社会分工越来越细,越来越专业化。各种产品有专门的工厂生产,彻底告别了自给自足的小农经济时代,这大大缩短了产品的生产周期,提高了生产效率。同样,在软件开发中能否做到软件对象的生产和使用相分离呢?能否在满足“开闭原则”的前提下,客户随意增删或改变对软件相关对象的使用呢?
     简单工厂模式违背了开闭原则,而“工厂方法模式”是对简单工厂模式的进一步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则。    

1.1.2  工厂方法模式的优缺点

(1)优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

(2)缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

1.1.3  工厂方法模式的应用场景

  • 客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
  • 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
  • 客户不关心创建产品的细节,只关心产品的品牌

1.1.4  简单工厂模式的结构和说明

 工厂方法模式的主要角色如下:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  • 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

工厂方法模式结构图如下图所示:

1.1.4  工厂方法模式的实现

//抽象产品:动物类
public interface Animal {
    public void show();
}
//具体产品:马类
public class Horse implements Animal {
    public void show() {
         System.out.println("我是一匹马");
    }
}
//具体产品:牛类
public class Cattle implements Animal {
    public void show() {
      System.out.println("我是一头牛");
    }
}
//抽象工厂:畜牧场
public interface AnimalFarmFactoty {
    public Animal newAnimal();
}
//具体工厂:养马场
public class HorseFarmFactoty implements AnimalFarmFactoty {
    public Animal newAnimal() {
        System.out.println("新马出生!");
        return new Horse();
    }
}
//具体工厂:养牛场
public class CattleFarmFactoty implements AnimalFarmFactoty {
    public Animal newAnimal() {
        System.out.println("新牛出生!");
        return new Cattle();
    }
}
public class Customer {
  public static void main(String[] args){
      AnimalFarmFactoty animalFarmFactoty = new HorseFarmFactoty();
      Horse horse = animalFarmFactoty.newAnimal();
      
      AnimalFarmFactoty animalFarmFactoty = new CattleFarmFactoty();
      Cattle cattle = animalFarmFactoty.newAnimal();
  }
}

 

注意:当需要生成的产品不多且不会增加,一个具体工厂类就可以完成任务时,可删除抽象工厂类。这时工厂方法模式将退化到简单工厂模式。

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
工厂模式是一种常见的创建型设计模式,用于创建对象,而不是通过直接调用构造函数来创建它们。工厂模式定义了一个接口,用于创建相关对象,但是让子类决定要实例化的类。在C++中,工厂模式可以通过以下步骤实现: 1. 创建一个抽象基类,该类定义了一个纯虚拟函数,该函数将返回一个指向基类的指针。这个基类就是我们的工厂接口。 ```c++ class Product { public: virtual ~Product() {} virtual void operation() = 0; }; ``` 2. 创建具体的产品类,它们继承自抽象基类,并实现了其纯虚拟函数。这些类就是我们的具体产品。 ```c++ class ConcreteProductA : public Product { public: void operation() override { /* 具体产品 A 的操作 */ } }; class ConcreteProductB : public Product { public: void operation() override { /* 具体产品 B 的操作 */ } }; ``` 3. 创建一个工厂类,该类实现了工厂接口,并根据需要创建具体的产品。这个工厂类就是我们的具体工厂。 ```c++ class Factory { public: virtual ~Factory() {} virtual std::unique_ptr<Product> createProduct() = 0; }; class ConcreteFactoryA : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductA>(); } }; class ConcreteFactoryB : public Factory { public: std::unique_ptr<Product> createProduct() override { return std::make_unique<ConcreteProductB>(); } }; ``` 4. 在客户端代码中使用具体工厂创建具体产品。 ```c++ int main() { std::unique_ptr<Factory> factory = std::make_unique<ConcreteFactoryA>(); std::unique_ptr<Product> product = factory->createProduct(); product->operation(); return 0; } ``` 这就是工厂模式的基本实现方式。通过这种方式,我们可以将对象的创建过程与客户端代码分离,从而更好地实现模块化和可扩展性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值