工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。
工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。
通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。
工厂模式的类型
1、简单工厂模式(Simple Factory Pattern):
- 简单工厂模式不是一个正式的设计模式,但它是工厂模式的基础。它使用一个单独的工厂类来创建不同的对象,根据传入的参数决定创建哪种类型的对象。
2、工厂方法模式(Factory Method Pattern):
- 工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法将对象的创建延迟到子类。
3、抽象工厂模式(Abstract Factory Pattern):
- 抽象工厂模式提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。
实际应用示例
假如说我们创建一个工厂,用来创造人,可以三种肤色的人,分别是黄人、白人、黑人
下面让我们用简单工厂模式来实现
简单工厂模式
类图如下图所示

结构组成
Product(产品角色):定义产品的公共接口或抽象类
ConcreteProduct(具体产品角色):实现Product接口的具体产品类
Factory(工厂角色):负责创建具体产品实例的类
首先创建接口,用来约定定义人的肤色和行为
java
public interface Human {
void printColor();
void talk();
}
下面我们实现接口
实现黄种人
java
public class YellowHuman implements Human{
@Override
public void printColor() {
System.out.println("黄人");
}
@Override
public void talk() {
System.out.println("黄人说话");
}
}
实现白种人
java
public class WhiteHuman implements Human{
@Override
public void printColor() {
System.out.println("白人");
}
@Override
public void talk() {
System.out.println("白人说话!");
}
}
实现黑种人
java
public class BlackHuman implements Human{
@Override
public void printColor() {
System.out.println("黑人");
}
@Override
public void talk() {
System.out.println("黑人说话");
}
}
目前三个人种的实体都已实现,都实体类种都实现了接口种人员说话和人种类别
下面让我们来创建工厂类
java
public class HumanFactory {
public static Human createHuman(String humanType){
if("black".equalsIgnoreCase(humanType)){
return new BlackHuman();
}else if("white".equalsIgnoreCase(humanType)){
return new WhiteHuman();
}else if ("yellow".equalsIgnoreCase(humanType)){
return new YellowHuman();
}else{
return null;
}
}
}
现在工厂类也创建好了,下面我们测试工厂类调用
java
@Test
public void test1(){
Human blackFactory = HumanFactory.createHuman("black");
blackFactory.printColor();
blackFactory.talk();
Human whiteFactory = HumanFactory.createHuman("white");
whiteFactory.printColor();
whiteFactory.talk();
Human yellowFactory = HumanFactory.createHuman("yellow");
yellowFactory.printColor();
yellowFactory.talk();
}
执行结果如下
java
黑人
黑人说话
白人
白人说话!
黄人
黄人说话
Process finished with exit code 0
下面让我们总结一下简单工厂模式的优缺点
优点:
1、封装性好:隐藏了对象创建的细节
2、扩展性强:新增产品只需要修改工厂类
3、解耦:客户端与具体产品类解耦
缺点:
1、违反开闭原则:添加新产品需要修改工厂类(添加新的需要在工厂类中添加if分支)
2、工厂职责过重:承担过多创建逻辑
3、可扩展性差:当产品类型过多的时候,工厂类会变得很复杂
适用场景
--创建对象的逻辑较为复杂
--客户端不需要知道具体的产品实现
--需要同意管理对象的创建过程
--产品类型相对固定且数量不多
与其他模式的关系
--工厂方法模式:是简单工厂模式的进一步抽象和改进
--抽象工厂模式:可以看作多个简单工厂的组合
--策略模式:在某些情况下可以互相替换使用
工厂方法模式
类图如下:

结构组成
Product(产品角色):定义产品的公共接口或抽象类
ConcreteProduct(具体产品角色):实现Product接口的具体产品类
Factory(抽象工厂角色):声明工厂方法,返回一个Product类型的对象
ConcreteFactory(具体工厂角色):实现抽象工厂方法,返回具体的Product实例
首先创建人的接口,用来约定人的肤色和行为
java
public interface Human {
void printColor();
void talk();
}
其次我们还来实现人种接口
java
public class BlackHuman implements Human {
@Override
public void printColor() {
System.out.println("黑人");
}
@Override
public void talk() {
System.out.println("黑人说话");
}
}
public class WhiteHuman implements Human {
@Override
public void printColor() {
System.out.println("白人");
}
@Override
public void talk() {
System.out.println("白人说话!");
}
}
public class YellowHuman implements Human {
@Override
public void printColor() {
System.out.println("黄人");
}
@Override
public void talk() {
System.out.println("黄人说话");
}
}
定义工厂的抽象方类
java
public abstract class AbstractHumanFactory {
public abstract Human createHuman();
}
实现工厂抽象类
java
public class BlackHumanFactory extends AbstractHumanFactory{
@Override
public Human createHuman() {
return new BlackHuman();
}
}
public class WhiteHumanFactory extends AbstractHumanFactory{
@Override
public Human createHuman() {
return new WhiteHuman();
}
}
public class YellowHumanFactory extends AbstractHumanFactory{
@Override
public Human createHuman() {
return new YellowHuman();
}
}
测试调用
java
开始黑人ShowTime
黑人
黑人说话
开始白人ShowTime
白人
白人说话!
开始黄人ShowTime
黄人
黄人说话
Process finished with exit code 0
下面我们总结一下工厂方法模式的优缺点
优点:
1、符合开闭原则:增加新产品只需要扩展具体工厂,无需修改现有代码
2、单一职责原则:每个工厂孩子负责创建特定类型的产品
3、可扩展性好:支持添加新的产品族
4、灵活性强:子类可以延迟对象的创建到合适的工厂
缺点:
1、类数量增多:每增加一个产品就需要增加一个对应的具体工厂类
2、复杂度增加:对于简单的产品创建,可能会显得过于复杂
3、层次较多:继承结构校审,可能导致系统复杂
适用场景
--产品等级结构稳定:产品种类基本不变,但具体实现经常变化
--需要隔离产品的创建和使用:客户端不关心产品如何创建的
--需要扩展产品系列:系统需要支持多种产品系列
--框架设计:为框架用户提供扩展点
与其他设计模式的关系
--简单工厂模式:工厂方法是对简单工厂的改进,解决了违反开闭原则的问题
--抽象工厂模式:工厂方法模式的扩展,用于创建产品族
--模板方法模式:工厂方法是模板方法的一种特殊应用
--策略模式:可以配合使用,工厂创建不同的策略对象
抽象工厂模式
在工厂方法模式中,一个具体的工厂负责生产一类具体的产品,即一对一的关系,但是如果需要一个具体的工厂生产多种产品对象,比如,生产不同肤色的男人和女人,那么就需要用到抽象工厂模式
类图如下

结构组成
AbstractFactory(抽象工厂):声明了一组创建抽象产品的抽象方法
ConcreteFactory(具体工厂):实现了创建具体产品的方法
AbstractProduct(抽象产品):定义了产品的规范
ConcreteProduct(具体产品):实现抽象产品接口的具体产品
Client(客户端):仅使用由抽象类型构成的系列产品
抽象工厂我们定义了两个方法,createMan()和createWoman()用来表示生产男人和女人,不管男人还是女人,都有不同的肤色,所以我们定义了三个子工厂用来创建不同肤色的人(包括男人和女人),这三个子工厂重写父类工厂的两个方法,具体实现如下
首先定义接口和两个实现类
java
public interface Human {
//打印肤色
public void printColor();
}
java
public abstract class Man implements Human{
public void pringGender(){
System.out.println("我是男性");
}
@Override
public abstract void printColor();
}
java
public abstract class Woman implements Human{
public void pringGender(){
System.out.println("我是女性");
}
@Override
public abstract void printColor();
}
其次我们来定义不同肤色的男人和女人
java
public class BlackMan extends Man{
@Override
public void printColor() {
System.out.println("我是黑人");
}
}
public class BlackWoman extends Woman{
@Override
public void printColor() {
System.out.println("我是黑人");
}
}
public class WhiteMan extends Man{
@Override
public void printColor() {
System.out.println("我是白人");
}
}
public class WhiteWoman extends Woman{
@Override
public void printColor() {
System.out.println("我是白人");
}
}
public class YellowMan extends Man{
@Override
public void printColor() {
System.out.println("我是黄种人");
}
}
public class YellowWoman extends Woman{
@Override
public void printColor() {
System.out.println("我是黄种人");
}
}
下面我们定义工厂抽象基类
java
public abstract class AbstractHumanFactory {
//创建男人
public abstract Man createMan();
//创人女人
public abstract Woman createWoman();
}
基类创建完成,下面实现各个人种工厂类,继承实现工厂抽象基类
java
public class BlackHumanFactory extends AbstractHumanFactory{
@Override
public Man createMan() {
return new BlackMan();
}
@Override
public Woman createWoman() {
return new BlackWoman();
}
}
java
public class WhiteHumanFactory extends AbstractHumanFactory{
@Override
public Man createMan() {
return new WhiteMan();
}
@Override
public Woman createWoman() {
return new WhiteWoman();
}
}
java
public class YellowHumanFactory extends AbstractHumanFactory{
@Override
public Man createMan() {
return new YellowMan();
}
@Override
public Woman createWoman() {
return new YellowWoman();
}
}
抽象工厂所有类定义完成,下面使用测试Demo测试
java
@Test
public void test3(){
com.lym.framework.factory.demofour.AbstractHumanFactory factory = null;
//创建黑人工厂
factory = new com.lym.framework.factory.demofour.BlackHumanFactory();
//创建黑人男人
Man blackMan = factory.createMan();
blackMan.printColor();
blackMan.pringGender();
//创建黑人女人
Woman blackWoman = factory.createWoman();
blackWoman.printColor();
blackWoman.pringGender();
//创建白人工厂
factory = new com.lym.framework.factory.demofour.WhiteHumanFactory();
//创建白人男人
Man whithMan = factory.createMan();
whithMan.printColor();
whithMan.pringGender();
//创建白人女人
Woman whiteWoman = factory.createWoman();
whiteWoman.printColor();
whiteWoman.pringGender();
//创建黄人工厂
factory = new com.lym.framework.factory.demofour.YellowHumanFactory();
//创建黄人男人
Man yellowMan = factory.createMan();
yellowMan.printColor();
yellowMan.pringGender();
//创建黄人女人
Woman yellowWoman = factory.createWoman();
yellowWoman.printColor();
yellowWoman.pringGender();
}
测试结果如下
java
我是黑人
我是男性
我是黑人
我是女性
我是白人
我是男性
我是白人
我是女性
我是黄种人
我是男性
我是黄种人
我是女性
Process finished with exit code 0
下面我们总结一下抽象工厂模式的优缺点
优点:
1、一致性保证:确保创建的产品对象属于同一产品族
2、易于切换产品族:只需要更换具体工厂即可
3、复核开闭原则:增加新产品族容易,只需要扩展具体工厂
4、封装性好:隐藏产品创建细节
增加固定类型产品的不同具体工厂比较方便,例如:现在要创建一个绿皮人,只需要再创建一个绿皮人的工厂继承抽象工厂就可以了
缺点:
1、扩展困难:增加新产品等级结构复杂
2、类数量多:每新增一个产品族就需要多个类
3、灵活性受限:难以混合不同产品族的对象
适用场景
--产品族存在:系统需要创建多个产品族中的产品对象
--产品约束关系:产品之间有约束关系,需要一起使用
--界面风格统一:需要创建具有相同主题的UI组件
--数据库访问层:不同数据库的连接和命令对象
与其他模式的关系
--工厂方法模式:抽象工厂通常使用工厂方法来实现
--建造者模式:都关注对象创建,但是抽象工厂关注产品族
--原型模式:可以结合使用,原型作为工厂创建的对象
--桥接模式:有时可以互换使用