工厂模式
- 实现工厂模式的方法
-
- 前置条件
- [简单工厂模式(Simple Factory)](#简单工厂模式(Simple Factory))
- [工厂方法模式(Factory Method)](#工厂方法模式(Factory Method))
- [抽象工厂模式(Abstract Factory)](#抽象工厂模式(Abstract Factory))
- 应用场景
- 总结
工厂模式(Factory Pattern) 是软件工程中的一种创建型设计模式。
使用工厂模式可以将对象的创建与使用分离,也就是说,客户端代码不需要知道具体创建的是哪种类型的对象,只需要关心对象的接口或抽象类即可。
工厂模式主要分为三种:
简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
实现工厂模式的方法
前置条件
1、工厂模式的前提需要以下两个部分 :
Product (产品接口): 定义了所有具体产品所共有的接口或抽象类。
ConcreteProduct (具体产品): 实现了Product接口的具体类。
2、演示代码:
定义people(人)的接口,相当于Product (产品接口)
定义student(学生)类实现people接口,相当于ConcreteProduct (具体产品)
定义teacher(教师)类实现people接口,相当于ConcreteProduct (具体产品)
csharp
//定义people(人)的接口,相当于Product (产品)
public interface People {
// 吃方法
void eat();
}
//定义student(学生)类实现people接口,相当于ConcreteProduct (具体产品)
public class Student implements People {
//重写eat方法
@Override
public void eat() {
System.out.println("student eat");
}
}
//定义teacher(教师)类实现people接口,相当于ConcreteProduct (具体产品)
public class Teacher implements People{
//重写eat()
@Override
public void eat() {
System.out.println("Teacher eat");
}
}
简单工厂模式(Simple Factory)
1、简单工厂模式的结构
Product (产品接口): 定义了所有具体产品所共有的接口或抽象类。
ConcreteProduct (具体产品): 实现了Product接口的具体类。
Factory (工厂类): 包含一个静态方法(通常是public static),根据输入参数决定创建哪个具体的产品实例,并返回该实例。
2、演示代码:
定义工厂类(SimpleFactory),根据输入参数,生产不同类型的人(产品)
csharp
/*
* 简单工厂模式
*/
public class SimpleFactory {
/*
* 根据传入的参数,创建不同的对象
* People是产品接口
* Student和Teacher是People的实现类,也就是具体产品
*/
public static People createPeople(String type) {
switch (type) {
case "student":
return new Student();
case "teacher":
return new Teacher();
default:
throw new IllegalArgumentException("Unknown people type");
}
}
}
3、测试:
csharp
public class Main {
//简单工厂模式测试
public static void main(String[] args) {
SimpleFactory simpleFactory = new SimpleFactory();
simpleFactory.createPeople("student").eat();
simpleFactory.createPeople("teacher").eat();
simpleFactory.createPeople("other" ).eat();
}
}
4、结果:
工厂方法模式(Factory Method)
1、工厂方法模式的结构
Product (产品接口): 定义了所有具体产品所共有的接口或抽象类。
ConcreteProduct (具体产品): 实现了Product接口的具体类。
Creator (创建者/工厂): 包含一个返回类型为Product的工厂方法,通常这个方法是抽象的,由具体的工厂去实现。
ConcreteCreator (具体创建者/具体工厂): 实现了工厂方法,负责创建具体产品的实例。
2、演示代码:
2.1、定义MethodPattern抽象类作为Creator (创建者/工厂),其中创建抽象的创建people的方法为抽象方法,统一调用people的eat方法为模板方法。
2.2、定义StudentMethodPattern类作为ConcreteCreator (具体创建者/具体工厂),继承MethodPattern抽象类并重写其中的抽象方法。
2.3、定义TeacherMethodPatten类作为ConcreteCreator (具体创建者/具体工厂),继承MethodPattern抽象类并重写其中的抽象方法。
csharp
/*
* 方法模式工厂
* 创建抽象的工厂类
*/
public abstract class MethodPattern {
// 创建抽象的创建people的方法,抽象方法
public abstract People createPeople();
//创建统一调用people的eat方法,模板方法
public void peopleEat() {
People people = createPeople();
people.eat();
}
}
/*
* 学生的工厂类
* 继承抽象的工厂类
*/
public class StudentMethodPattern extends MethodPattern{
//重写赋值方法,完成people对象的赋值,返回学生对象
@Override
public People createPeople() {
return new Student();
}
}
/*
* 教师的工厂类
* 继承抽象的工厂类
*/
public class TeacherMethodPatten extends MethodPattern{
//重写赋值方法,完成people对象的赋值,返回教师对象
@Override
public People createPeople() {
return new Teacher();
}
}
3、测试:
csharp
public class Main {
//方法模式测试
public static void main(String[] args) {
//通过学生的工厂创建对应的pstudent对象,调用其中的eat方法
new StudentMethodPattern().createPeople().eat();
new TeacherMethodPatten().createPeople().eat();
}
}
4、结果:
抽象工厂模式(Abstract Factory)
1、工厂方法模式的结构
Product (产品接口): 定义了所有具体产品所共有的接口或抽象类。
ConcreteProduct (具体产品): 实现了Product接口的具体类。
AbstractFactory (抽象工厂): 定义了一个接口,用于创建一组相关或依赖的对象,但没有指定具体的产品类。通常包含多个创建产品的抽象方法。
ConcreteFactory (具体工厂): 实现了AbstractFactory接口,负责创建具体产品族中的所有产品实例。
Client (客户端): 只依赖于抽象工厂和抽象产品接口,而不直接依赖任何具体工厂或具体产品类。
2、演示代码:
2.1、定义AbstractFactory接口作为AbstractFactory (抽象工厂),将创建People方法抽象出来。
2.2、定义StudentAbstractFactory类,实现AbstractFactory接口,作为ConcreteFactory (具体工厂),重写其中的创建people的方法,返回学生对象。
2.3、定义TeacherAbstractFactory类,实现AbstractFactory接口,作为ConcreteFactory (具体工厂),重写其中的创建people的方法,返回教师对象。
2.4、定义Client类,作为Client (客户端)。创建构造方法,传入工厂,通过传入不同的工厂,给people赋值不同的实体对象。同时调用实体对象的eat方法。
csharp
//抽象工厂方法
public interface AbstractFactory {
//将创建People方法抽象出来。
People createPeople();
}
/*
*学生的抽象工厂实现
*/
public class StudentAbstractFactory implements AbstractFactory{
//重写其中的创建people的方法,返回学生对象。
@Override
public People createPeople() {
return new Student();
}
}
/*
*教师的抽象工厂实现
*/
public class TeacherAbstractFactory implements AbstractFactory{
//重写其中的创建people的方法,返回教师对象。
@Override
public Teacher createPeople() {
return new Teacher();
}
}
/**
*工厂的客户端
**/
public class Client {
//定义私有化的people
private People people;
//构造方法,传入工厂,通过传入不同的工厂,给people赋值不同的实体对象
public Client(AbstractFactory factory){
this.people = factory.createPeople();
}
//调用实体对象的eat方法
public void eat(){
people.eat();
}
}
3、测试:
csharp
public class Main {
//测试抽象工厂模式
public static void main(String[] args) {
//通过抽象工厂创建学生的对象,调用其中的eat方法
Client TeacherClient = new Client(new TeacherAbstractFactory());
TeacherClient.eat();
//通过抽象工厂创建教师的对象,调用其中的eat方法
Client StudentClient = new Client(new StudentAbstractFactory());
StudentClient.eat();
}
}
4、结果:
应用场景
简单工厂模式:
1、配置文件解析器选择: 根据配置文件的类型(如XML、JSON、YAML),使用简单工厂模式来创建相应的解析器。
2、支付网关集成 :在一个电子商务平台中,根据用户选择的支付方式(如信用卡、PayPal、支付宝)动态地创建对应的支付处理器。
3、日志记录器管理: 根据环境(开发、测试、生产)选择不同的日志记录方式(如控制台输出、文件记录、远程服务器发送)。
工厂方法模式:
1、数据库连接池 :根据应用程序配置或运行时参数,选择适当的数据库类型(如MySQL、PostgreSQL、Oracle),并创建相应的数据库连接实例。
2、报表生成工具:依据用户需求生成不同格式的报告(如PDF、Excel、Word),每个格式由特定的工厂方法创建。
抽象工厂模式
1、多平台GUI库 :为跨多个操作系统的桌面应用程序创建统一的用户界面组件集,保证所有组件来自同一个家族,以维持一致的外观和行为。
2、游戏开发中的角色和敌人生成 :根据不同关卡或玩家选择的角色类型,创建一系列相关的游戏角色或敌人,保持游戏内部的一致性和规则性。
3、插件系统:允许第三方开发者为应用程序添加额外的功能模块(如编辑器插件、IDE扩展)。每个插件可以有自己的服务或工具窗口,但都遵循一套共同的接口规范。
总结
简单工厂模式
优点:
简化客户端代码:客户端不需要直接实例化具体的产品类,只需调用工厂类的方法即可获取所需的对象。
集中管理创建逻辑:所有创建逻辑集中在工厂类中,便于维护和调试。
易于理解和实现:概念简单,容易上手,适合快速原型开发。
缺点:
违反开闭原则:每当添加新产品类型时,需要修改工厂类中的创建逻辑,这违背了面向对象设计的开闭原则(对扩展开放,对修改关闭)。
职责过重:随着产品类型的增加,工厂类可能会变得庞大且难以维护。
工厂方法模式
优点:
支持开闭原则:通过新增具体工厂类和具体产品类来扩展系统,而无需改动现有代码,符合开闭原则。
灵活性高:允许子类决定应该实例化哪一个具体的产品类,从而将对象的创建与使用解耦。
易于扩展:可以轻松地向系统中添加新的产品类型,只需添加相应的具体工厂类和具体产品类即可。
缺点:
引入额外的类:增加了系统的复杂度,因为需要为每个具体产品创建对应的工厂类。
潜在的重复代码:如果多个工厂类之间的差异很小,可能会导致代码冗余。
抽象工厂模式
优点:
创建一系列相关对象:非常适合创建一系列相关或相互依赖的对象,确保它们属于同一个家族或主题。
保持一致性:保证所有相关的对象都是一致的,并且遵循相同的规则,特别适用于多平台或多个主题的支持。
高度灵活:可以在运行时动态地改变整个产品系列,而不需要修改客户端代码。
缺点:
复杂度较高:相比其他工厂模式,抽象工厂模式更为复杂,增加了理解成本。
实现难度大:实现抽象工厂模式可能需要更多的前期工作,并且在小型项目中可能显得过于繁琐。
总结
简单工厂模式适合小型项目或需求不明确的情况,它简化了对象创建过程,但不太适合长期维护的大规模应用。
工厂方法模式则更适合大型项目,尤其是在需要扩展新功能而不改变现有代码的情况下,它提供了更好的灵活性和可维护性。
抽象工厂模式适用于需要创建一系列相关对象的场景,特别是当这些对象必须保持一致性和相互依赖时,它可以确保所有相关对象都来自同一个家族。