介绍
工厂模式(Factory Pattern)是一种常用的创建型设计模式,也叫做工厂方法模式(Factory Method Pattern),它提供了一种创建对象的最佳方式。在工厂模式中,我们不再直接通过 new 来创建对象,而是通过一个工厂类来间接地创建对象。主要包含以下几个角色:
-
抽象产品(Product):定义产品的接口或抽象类,具体产品由其子类实现。
-
具体产品(Concrete Product):实现抽象产品接口的具体类,是被创建的对象。
-
抽象工厂(Factory):提供创建产品对象的接口或抽象类,具体工厂由其子类实现。
-
具体工厂(Concrete Factory):实现抽象工厂接口的具体类,具有生产不同具体产品的能力。
使用工厂模式能够将对象的创建和使用分离,可以降低系统的耦合度,提高系统的可扩展性和可维护性。常见的应用场景包括日志记录器、数据库访问、窗口创建等。
类型
工厂模式通常分为三种类型:
-
简单工厂模式(Simple Factory Pattern):又称静态工厂方法模式,它由一个工厂类根据传入的参数决定创建出哪一种产品类的实例。简单工厂模式适用于产品种类较少且不经常变化的情况。
-
工厂方法模式(Factory Method Pattern):是针对简单工厂模式缺点而产生的。在工厂方法模式中,每个具体产品都对应一个具体工厂,每个具体工厂只能创建一个具体产品对象,但是可以通过添加新的具体工厂来创建新的具体产品。
-
抽象工厂模式(Abstract Factory Pattern):又称工具箱模式,提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类。抽象工厂模式适用于产品族和产品等级结构比较复杂的情况。
示例
场景,根据组织orgId,生成不同的文件夹路径。
简单工厂模式
好的,我可以为您提供一个基于简单工厂模式的实现,具体如下:
首先,我们需要定义抽象产品类 AbstractFolder
,用于描述文件夹的基本属性和功能。本例中,我们只需要使用其中的 getFolderPath()
方法即可。
java
public abstract class AbstractFolder {
public abstract String getFolderPath(String orgId);
}
接下来,我们需要创建两个具体产品类 DepartmentFolder
和 EmployeeFolder
,它们分别代表组织机构的部门文件夹和员工文件夹,两个类都要实现 getFolderPath()
方法。
java
public class DepartmentFolder extends AbstractFolder {
@Override
public String getFolderPath(String orgId) {
return "organizations/" + orgId + "/departments/";
}
}
public class EmployeeFolder extends AbstractFolder {
@Override
public String getFolderPath(String orgId) {
return "organizations/" + orgId + "/employees/";
}
}
最后,我们需要创建一个工厂类 FolderFactory
,用于根据传入参数 orgId
来创建对应的文件夹对象。当传入的 orgId
为 DEPARTMENT
时,返回 DepartmentFolder
对象;当传入的 orgId
为 EMPLOYEE
时,返回 EmployeeFolder
对象。
java
public class FolderFactory {
public static AbstractFolder createFolder(String orgId) {
if ("DEPARTMENT".equals(orgId)) {
return new DepartmentFolder();
} else if ("EMPLOYEE".equals(orgId)) {
return new EmployeeFolder();
} else {
throw new IllegalArgumentException("Invalid orgId: " + orgId);
}
}
}
这样,当调用 FolderFactory.createFolder("DEPARTMENT").getFolderPath("company")
时,会返回 "organizations/company/departments/"
的字符串,调用 FolderFactory.createFolder("EMPLOYEE").getFolderPath("company")
时,会返回 "organizations/company/employees/"
的字符串。
希望这个示例能够帮助您理解如何使用简单工厂模式实现您的需求。
工厂方法模式
好的,针对您的需求,我们可以把简单工厂模式改为工厂方法模式。工厂方法模式中,每个具体产品类都有一个对应的工厂类,用于创建该产品类的实例。
首先,我们仍然需要定义抽象产品类 AbstractFolder
,其代码和之前一样:
java
public abstract class AbstractFolder {
public abstract String getFolderPath(String orgId);
}
接下来,我们需要创建两个具体产品类 DepartmentFolder
和 EmployeeFolder
,它们分别代表组织机构的部门文件夹和员工文件夹,两个类依然都要实现 getFolderPath()
方法,与之前一致:
java
public class DepartmentFolder extends AbstractFolder {
@Override
public String getFolderPath(String orgId) {
return "organizations/" + orgId + "/departments/";
}
}
public class EmployeeFolder extends AbstractFolder {
@Override
public String getFolderPath(String orgId) {
return "organizations/" + orgId + "/employees/";
}
}
接下来是关键的部分:我们需要创建两个工厂类 DepartmentFolderFactory
和 EmployeeFolderFactory
,它们分别用于创建 DepartmentFolder
和 EmployeeFolder
对象。
java
public class DepartmentFolderFactory implements FolderFactory {
@Override
public AbstractFolder createFolder() {
return new DepartmentFolder();
}
}
public class EmployeeFolderFactory implements FolderFactory {
@Override
public AbstractFolder createFolder() {
return new EmployeeFolder();
}
}
这里的 FolderFactory
是一个接口,其中定义了一个 createFolder()
方法,用于创建抽象产品类的实例。
最后,我们需要让客户端使用这些工厂类创建对象。客户端只需要知道要创建哪种类型的文件夹,在运行时再传入对应的工厂类即可。
java
public interface FolderFactory {
AbstractFolder createFolder();
}
public class Client {
public static void main(String[] args) {
String orgId = "company";
FolderFactory departmentFactory = new DepartmentFolderFactory();
AbstractFolder departmentFolder = departmentFactory.createFolder();
System.out.println(departmentFolder.getFolderPath(orgId));
FolderFactory employeeFactory = new EmployeeFolderFactory();
AbstractFolder employeeFolder = employeeFactory.createFolder();
System.out.println(employeeFolder.getFolderPath(orgId));
}
}
这个示例中,我们通过两个工厂类分别创建了部门文件夹和员工文件夹,并调用了它们的 getFolderPath()
方法。
希望这个示例能够帮助您理解如何使用工厂方法模式实现您的需求。
抽象工厂模式
好的,针对您的需求,我们可以把工厂方法模式改为抽象工厂模式。在抽象工厂模式中,一个工厂类可以创建多个产品族(相关联的一组产品),而在工厂方法模式中,一个工厂类只能创建同一产品等级结构(一类产品)的产品。
首先,我们需要定义两个抽象产品类 AbstractDepartmentFolder
和 AbstractEmployeeFolder
,其代码和之前的 AbstractFolder
类相似:
java
public abstract class AbstractDepartmentFolder {
public abstract String getDepartmentFolderPath(String orgId);
}
public abstract class AbstractEmployeeFolder {
public abstract String getEmployeeFolderPath(String orgId);
}
接下来,我们需要创建两个具体产品类 DepartmentFolder
和 EmployeeFolder
,它们分别实现 AbstractDepartmentFolder
和 AbstractEmployeeFolder
接口,依然分别代表部门文件夹和员工文件夹,代码如下:
java
public class DepartmentFolder implements AbstractDepartmentFolder {
@Override
public String getDepartmentFolderPath(String orgId) {
return "organizations/" + orgId + "/departments/";
}
}
public class EmployeeFolder implements AbstractEmployeeFolder {
@Override
public String getEmployeeFolderPath(String orgId) {
return "organizations/" + orgId + "/employees/";
}
}
然后,我们需要定义一个抽象工厂类 AbstractFolderFactory
来创建 AbstractDepartmentFolder
和 AbstractEmployeeFolder
两个产品族。其中定义了两个工厂方法 createDepartmentFolder()
和 createEmployeeFolder()
用于创建部门文件夹和员工文件夹对应的产品。
java
public abstract class AbstractFolderFactory {
public abstract AbstractDepartmentFolder createDepartmentFolder();
public abstract AbstractEmployeeFolder createEmployeeFolder();
}
接下来,我们创建两个具体工厂类 DefaultFolderFactory
和 CustomizedFolderFactory
,分别对应默认的文件夹路径和定制化的文件夹路径。这两个具体工厂类实现了抽象工厂类中的两个工厂方法,分别创建 DepartmentFolder
和 EmployeeFolder
对象。
java
public class DefaultFolderFactory extends AbstractFolderFactory {
@Override
public AbstractDepartmentFolder createDepartmentFolder() {
return new DepartmentFolder();
}
@Override
public AbstractEmployeeFolder createEmployeeFolder() {
return new EmployeeFolder();
}
}
public class CustomizedFolderFactory extends AbstractFolderFactory {
@Override
public AbstractDepartmentFolder createDepartmentFolder() {
// 这里是定制化的部门文件夹路径
return new DepartmentFolderCustomized();
}
@Override
public AbstractEmployeeFolder createEmployeeFolder() {
// 这里是定制化的员工文件夹路径
return new EmployeeFolderCustomized();
}
}
最后,我们需要让客户端使用这些工厂类创建对象。客户端只需要知道要创建哪种类型的工厂,在运行时再传入对应的工厂即可。
java
public class Client {
public static void main(String[] args) {
String orgId = "company";
AbstractFolderFactory defaultFactory = new DefaultFolderFactory();
AbstractDepartmentFolder departmentFolder = defaultFactory.createDepartmentFolder();
AbstractEmployeeFolder employeeFolder = defaultFactory.createEmployeeFolder();
System.out.println(departmentFolder.getDepartmentFolderPath(orgId));
System.out.println(employeeFolder.getEmployeeFolderPath(orgId));
AbstractFolderFactory customizedFactory = new CustomizedFolderFactory();
AbstractDepartmentFolder customizedDepartmentFolder = customizedFactory.createDepartmentFolder();
AbstractEmployeeFolder customizedEmployeeFolder = customizedFactory.createEmployeeFolder();
System.out.println(customizedDepartmentFolder.getDepartmentFolderPath(orgId));
System.out.println(customizedEmployeeFolder.getEmployeeFolderPath(orgId));
}
}
这个示例中,我们通过两个抽象工厂类分别创建默认的和定制化的文件夹路径,然后分别使用 createDepartmentFolder()
和 createEmployeeFolder()
方法创建部门文件夹和员工文件夹,并调用它们的 getDepartmentFolderPath()
和 getEmployeeFolderPath()
方法。
希望这个示例能够帮助您理解如何使用抽象工厂模式实现您的需求。