# 工厂和抽象工厂模式

## 1. 简介

先来简单说一下什么是工厂模式和抽象工厂模式：

* 工厂模式：一般我们通过new创建一个产品类，为了简化操作我们可以创建一个工厂类，由这个工厂类负责创建所需要的产品；
* 抽象工厂模式：如果产品的种类多了，使用一个工厂可能不够，会导致逻辑复杂，可读性差等。这个时候我们可以定义一个工厂接口，通过多个工厂实现类来处理不同的产品。

## 2. 普通工厂

### 2.1 普通工厂UML

![](https://3037548586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnpynfpU0w3FBTJVlOK%2Fsync%2F1c709ac3b92d0d919c6c59763d8e2429b91b063c.png?generation=1589894630002408\&alt=media)

### 2.2 普通工厂实例

产品接口：

```java
package com.wangjun.designPattern.factory;

public interface IProduct {

    public String info();

}
```

产品实现类：

```java
package com.wangjun.designPattern.factory;

public class Product1 implements IProduct {

    @Override
    public String info() {
        return "Product1";
    }

}
```

其余4个Product类一样，就不写了。

工厂类：

```java
package com.wangjun.designPattern.factory;

public class ProductFactory {

    public static IProduct createProduct(int type) {

        switch(type) {
            case 1:
                return new Product1();
            case 2:
                return new Product2();
            case 3:
                return new Product3();
            case 4:
                return new Product4();
            case 5:
                return new Product5();
            default:
                System.out.println("没有此型号的产品");
                return null;
        }
    }

}
```

测试类：

```java
package com.wangjun.designPattern.factory;

public class Main {

    public static void main(String[] args) {
         //根据传入的参数来创建具体的类
        IProduct product1 = ProductFactory.createProduct(1);
        System.out.println("产品名：" + product1.info());

        IProduct product2 = ProductFactory.createProduct(2);
        System.out.println("产品名：" + product2.info());

        IProduct product3 = ProductFactory.createProduct(3);
        System.out.println("产品名：" + product3.info());
    }

}
```

运行结果：

```java
产品名：Product1
产品名：Product2
产品名：Product3
```

## 3. 抽象工厂

### 3.1 抽象工厂示意图

![](https://3037548586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnpynfpU0w3FBTJVlOK%2Fsync%2F04e2076abc6a7aed1ffd7d31e0ce606117678125.png?generation=1589894629845598\&alt=media)

### 3.2 抽象工厂UML

![](https://3037548586-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LnpynfpU0w3FBTJVlOK%2Fsync%2F93db50d4aeb60259f9cd9a3275b651ea10f1b4ed.png?generation=1589894630443788\&alt=media)

### 3.3 抽象工厂实例

工厂接口：

```java
package com.wangjun.designPattern.abstractFactory;

public interface IFactory {

    public IProduct createProduct(int type);

}
```

工厂实现类：

```java
package com.wangjun.designPattern.abstractFactory;

public class Factory1 implements IFactory {

    @Override
    public IProduct createProduct(int type) {
        System.out.println("工厂1生产");
        if(type == 1) {
            return new Product1();
        }else if(type == 2) {
            return new Product2();
        }else {
            System.out.println("不支持此类型的产品");
        }
        return null;
    }

}
```

工程2,3一样，就不写了。

产品接口：

```java
package com.wangjun.designPattern.abstractFactory;

public interface IProduct {

    public String info();

}
```

产品实现类：

```java
package com.wangjun.designPattern.abstractFactory;

public class Product1 implements IProduct {

    @Override
    public String info() {
        return "Product1";
    }

}
```

产品实现类2,3,4,5,6一样就不写了。

提供给外部调用的工程类：

```java
package com.wangjun.designPattern.abstractFactory;

public class ProductFactory {

    public static IProduct createProduct(int type) {
        IFactory factory = null;

        //1,2类型使用工厂1生成；3,4类型使用工厂2生产；5,6类型使用工厂3生产
        if(type >= 1 && type <= 2) {
            factory = new Factory1();
        }else if(type >=3 && type <= 4) {
            factory = new Factory2();
        }else if(type >= 5 && type <= 6) {
            factory = new Factory3();
        }else {
            System.out.println("不支持此类型的产品");
            return null;
        }

        IProduct product = factory.createProduct(type);

        return product;
    }

}
```

测试类：

```java
package com.wangjun.designPattern.abstractFactory;

public class Main {

    public static void main(String[] args) {
        IProduct product1 = ProductFactory.createProduct(1);
        System.out.println("产品名：" + product1.info());

        IProduct product2 = ProductFactory.createProduct(4);
        System.out.println("产品名：" + product2.info());

        IProduct product3 = ProductFactory.createProduct(5);
        System.out.println("产品名：" + product3.info());
    }

}
```

打印输出：

```
工厂1生产
产品名：Product1
工厂2生产
产品名：Product4
工厂3生产
产品名：Product5
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jun-wang.gitbook.io/learnjava/ji-shu-xue-xi/java-she-ji-mo-shi/gong-chang-he-chou-xiang-gong-chang-mo-shi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
