设计模式——工厂模式

工厂模式

  • 实现工厂模式的方法
    • 前置条件
    • [简单工厂模式(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扩展)。每个插件可以有自己的服务或工具窗口,但都遵循一套共同的接口规范。

总结

简单工厂模式
优点:

简化客户端代码:客户端不需要直接实例化具体的产品类,只需调用工厂类的方法即可获取所需的对象。

集中管理创建逻辑:所有创建逻辑集中在工厂类中,便于维护和调试。

易于理解和实现:概念简单,容易上手,适合快速原型开发。
缺点:

违反开闭原则:每当添加新产品类型时,需要修改工厂类中的创建逻辑,这违背了面向对象设计的开闭原则(对扩展开放,对修改关闭)。

职责过重:随着产品类型的增加,工厂类可能会变得庞大且难以维护。

工厂方法模式
优点:

支持开闭原则:通过新增具体工厂类和具体产品类来扩展系统,而无需改动现有代码,符合开闭原则。

灵活性高:允许子类决定应该实例化哪一个具体的产品类,从而将对象的创建与使用解耦。

易于扩展:可以轻松地向系统中添加新的产品类型,只需添加相应的具体工厂类和具体产品类即可。
缺点:

引入额外的类:增加了系统的复杂度,因为需要为每个具体产品创建对应的工厂类。

潜在的重复代码:如果多个工厂类之间的差异很小,可能会导致代码冗余。

抽象工厂模式
优点:

创建一系列相关对象:非常适合创建一系列相关或相互依赖的对象,确保它们属于同一个家族或主题。

保持一致性:保证所有相关的对象都是一致的,并且遵循相同的规则,特别适用于多平台或多个主题的支持。

高度灵活:可以在运行时动态地改变整个产品系列,而不需要修改客户端代码。
缺点:

复杂度较高:相比其他工厂模式,抽象工厂模式更为复杂,增加了理解成本。

实现难度大:实现抽象工厂模式可能需要更多的前期工作,并且在小型项目中可能显得过于繁琐。

总结

简单工厂模式适合小型项目或需求不明确的情况,它简化了对象创建过程,但不太适合长期维护的大规模应用。

工厂方法模式则更适合大型项目,尤其是在需要扩展新功能而不改变现有代码的情况下,它提供了更好的灵活性和可维护性。

抽象工厂模式适用于需要创建一系列相关对象的场景,特别是当这些对象必须保持一致性和相互依赖时,它可以确保所有相关对象都来自同一个家族。

相关推荐
Jack_hrx1 小时前
全面教程:Nacos 2.3.2 启用鉴权与 MySQL 数据存储配置
java·nacos·nacos鉴权·nacos配置mysql
阿杰学编程2 小时前
1、什么是GO
服务器·开发语言·golang
有梦想的咸鱼_2 小时前
Golang 设计模式
开发语言·设计模式·golang
一决威严-雪雪2 小时前
springboot整合gateway
java·开发语言
bboysky452 小时前
golang 的 panic
开发语言·后端·golang
小诸葛的博客2 小时前
Go oom分析(一)——使用pprof线上分析
开发语言·后端·golang
丁卯4042 小时前
golang单元测试
开发语言·golang·单元测试
SyntaxSage2 小时前
Lua语言的软件开发工具
开发语言·后端·golang
凉秋girl2 小时前
Java基础概念
java·开发语言
ChoSeitaku3 小时前
No.1|Godot|俄罗斯方块复刻|棋盘和初始方块的设置
java·前端·godot