# Factory 工厂模式

## 为什么需要工厂模式?

假设有这么一个场景：

有一家大型国际化公司需要开发一个主页，该公司总部在法国，但主要业务在中国和美国，所以说主页需要有两个版本，一个是中文版针对中国，一个是英文版针对美国。中文版主页由中国的团队开发，英文版主页由美国团队开发。

现在有一个业务需求：法国总部的程序员根据用户的所在国家决定返回一个中文版网页还是英文版网页。

位于法国总部的程序员并不知道 中文版网页和英文版具体是怎样实现的，但是他们又要能够根据用户的所在地来选择给用户看到的 是中文版主页还是英文版主页。

法国程序员 可以 直接 new 一个 写好了的 中文版网页对象 或者 英文版网页对象，但是这样做是利于维护的。比如:

* 中文版 对象内部实现发生变化，构造函数也变了(比如参数不用，参数顺序不同)，总部程序员不知道，那么 new 传参给构造函数也非常有可能出错。

为了解决这种问题， 接口 派上了用场.。假设中文版主页和英文版主页实现了某一个接口，调用主页的程序员只需要拿到这个接口就可以了。 为此，还需要一个根据用户所在国家来判断的应该调用哪个主页的类，这个类 就是工厂类。

整个过程可以用下面这个图表示:

![](https://3876120153-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MeAUhQfs4IbJtX3pwu_%2F-Me_3nDbuusGjaL8igcI%2F-Me_6zmv8SARakvSs-hQ%2Ffactory.png?alt=media\&token=9cbca9cd-3620-4fd5-88f2-688e1b78791f)

按照这个图去实现程序，也叫做 工厂模式。

## 具体代码实现

我们编写了一个接口 IHomePage， 内含一个 ShowInfo() 函数， 用来返回网站的主页信息。

```java
public interface IHomePage {
    public String showInfo();
}
```

我们另外定义了两个主页类  ChinesHomePage 和 EnglishHomePage 。

```java
public class ChineseHomePage implements IHomePage{
    @Override
    public String showInfo() {
        return "这是中文首页.";
    }
}
```

```java
public class EnglishHomePage implements IHomePage {
    @Override
    public String showInfo() {
        return "This USA home page. ";
    }
}
```

&#x20;我们定义了一个工厂类 HomePageFactory , 用来调用网页接口。

```java
public class HomePageFactory {
    public static IHomePage getHomePage(String country){
        if (country.equals("China")){
            return new ChineseHomePage();
        }else if (country.equals("USA")){
            return new EnglishHomePage();
        }else {
            return null;
        }
    }
}
```

最后我们定义了一个用户类 HomePageSelector

```java
public class HomePageSelector {
    public static void main(String[] args) {

        //通过 工厂类 来实例化一个对象
        // 对象类型为接口, 但并不是真的实例化一个接口, 接口本身是不能被实例化的
        IHomePage hp1 = HomePageFactory.getHomePage("China");
        IHomePage hp2 = HomePageFactory.getHomePage("USA");


        System.out.println(hp1.showInfo());//输出:这是中文首页.
        System.out.println(hp2.showInfo());//输出:This USA home page.
    }
}
```
