当前位置: 首页 > news >正文

工厂模式:简单工厂、工厂方法以及抽象工厂

文章目录

  • 前言
  • 简单工厂模式
    • 优缺点
  • 工厂方法模式
    • 优缺点
  • 抽象工厂
    • 优缺点

前言

工厂模式是一种创建型设计模式,其作用是将对象的创建和使用进行解耦,用于提高代码的可维护性和可扩展性。通过提供给外部负责创建对象的工厂类,外部类通过工厂来创建对象。工厂模式包括简单工厂、工厂方法以及抽象工厂三种模式。

简单工厂模式

简单工厂模式如其名,非常简单,定义一个工厂类,提供给外部创建对象的方法,会根据传入的参数创建不同的对象。

代码实现:

/*水果接口*/
public interface Fruit {
}
/* 水果接口的两个具体的实现类 */
public class Apple implements Fruit{
}
public class Pear implements Fruit{
}
/* 创建对象的工厂*/
public class FruitFactory {

    public Fruit creat(String fruit){
        if (fruit.equals("apple")){
            return new Apple();
        }else if (fruit.equals("pear")){
            return new Pear();
        }
        throw  new IllegalArgumentException("参数值输入不正确");
    }
}

优缺点

优点:代码实现简单,如果需要扩展对象的创建不需要额外创建类
缺点:不符合开闭原则,若要扩展对象的创建会修改工厂类的代码
开闭原则:对扩展是开放的,对修改是关闭的。在不修改原代码的前提下进行行为的扩展。

工厂方法模式

工厂方法模式,其实现需要定义一个接口/抽象类以及创建对象的抽象方法,并且定义多个具体工厂,继承或者实现抽象工厂类,并重写其抽象方法,完成具体对象的创建。
代码实现:

/*抽象工厂类*/
public interface IFruitFactory {
    abstract Fruit create();
}

/* 苹果工厂类*/
public class AppleFactory implements IFruitFactory{
    @Override
    public Fruit create() {
        return new Apple();
    }
}
/*梨工厂类 */
public class PearFactory implements IFruitFactory{
    @Override
    public Fruit create() {
        return new Pear();
    }
}
/*测试*/
public class Test {
    public static void main(String[] args) {
    // 创建对应对象的工厂类
        IFruitFactory factory=new AppleFactory();
    // 根据具体工厂的创建行为创建对象
        Fruit fruit = factory.create();
        System.out.println(fruit);
    }
}

优缺点

优点:符合开闭原则,当需要扩展对象的创建时,只需要扩展一个工厂类即可。
缺点:每次进行扩展都需要定义一个新的类

抽象工厂

对于一些存在关系的类,例如公司和产品,一个公司有许多产品。举个具体的例子,小米和苹果是两个公司,它们有很多相同的产品种类,例如手机、电脑等等。而抽象工厂模式则是定义一个抽象工厂类,其包含多个产品创建的抽象方法,通过创建具体工厂继承或实现抽象工厂,重写其方法完成产品的具体创建。

/*汽车、手机、电脑的接口*/
public interface Computer {
    abstract void go();
}
public interface Phone {
    abstract void begin();
}
public interface Car {
    abstract void start();
}
/*具体的实现类*/
public class MiCar implements Car{
    @Override
    public void start() {
        System.out.println("小米汽车启动");
    }
}
public class MiComputer implements Computer{
    @Override
    public void go() {
        System.out.println("小米电脑开机");
    }
}
public class MiPhone implements Phone{
    @Override
    public void begin() {
        System.out.println("小米手机启动");
    }
}
苹果的实现类省略。。。

/*我们不妨定义一个抽象工厂,其包含公司各个产品的创建方法*/
public abstract ICompany {
    abstract Car getCar();
    abstract Computer getComputer();
    abstract Phone getPhone();
}
/*具体工厂*/
public class MiCompany extend ICompany{
    @Override
    public Car getCar() {
        return new MiCar();
    }

    @Override
    public Computer getComputer() {
        return new MiComputer();
    }

    @Override
    public Phone getPhone() {
        return new MiPhone();
    }
}

public class AppleCompany extend ICompany{
    @Override
    public Car getCar() {
        return new AppleCar();
    }

    @Override
    public Computer getComputer() {
        return new AppleComputer();
    }

    @Override
    public Phone getPhone() {
        return new ApplePhone();
    }
}

测试:
public class Test {
/*指定具体的工厂类以及方法创建对象*/
    public static void main(String[] args) {
        ICompany company=new AppleCompany();
        Car car = company.getCar();
        car.start();
        ICompany company1=new MiCompany();
        Computer computer = company1.getComputer();
        computer.go();
    }
}

抽象工厂和工厂方法相比,其实两者很像但是也存在区别,两者都是创建抽象类,以及创建具体的实现类,由实现类完成对象的具体的创建。两者的区别在于工厂方法针对一个接口,抽象工厂针对一组存在依赖关系的接口。

优缺点

优点:可以减少类的创建,对于上面举得例子,我们完成每个具体对象的创建其实只定义了三个类,一个是抽象工厂,另外两个是具体的工厂。如果我们使用工厂方法来做,需要定义手机抽象工厂、汽车抽象工厂、电脑抽象工厂,以及小米手机具体工厂、苹果手机具体工厂…会多了很多类。
缺点:不符合开闭原则,并且扩展比较复杂,如果新增一些其他行为,例如电视的创建,就需要修改抽象工厂以及具体工厂的代码。

相关文章:

  • 重定位(2)
  • Qt的QDateTimeEdit控件的使用
  • 并发编程(线程安全)面试题及原理
  • 华为云IAM 用户名和IAM ID
  • 在Blender中给SP分ID通道图
  • 后路式编程
  • Java进阶-SpringCloud设计模式-工厂模式的设计与详解
  • Linux软件包管理
  • 2025最新Transformer模型及深度学习前沿技术应用
  • go语言因为前端跨域导致无法访问到后端解决方案
  • React + TypeScript 实战指南:用类型守护你的组件
  • MVTec HDevelopEVO 24.11体验
  • MsBox.Avalonia 全局修改弹框样式
  • Gradle 配置 Lombok 项目并发布到私有 Maven 仓库的完整指南
  • ​DeepSeek:如何通过自然语言生成HTML文件与原型图?
  • Calico-基本安装、IPIP同节点通信和Proxy_ARP实践 Day01
  • CentOS 7 aarch64上制作kernel rpm二进制包 —— 筑梦之路
  • leetcode day25 28 KMP算法
  • 【ESP-ADF】在 VSCode 安装 ESP-ADF 注意事项
  • 统计建模小贴士
  • 李家超:明日起香港特区护照持有人可免签入境阿联酋
  • 习近平会见哥伦比亚总统佩特罗
  • 俄乌拟在土耳其举行会谈,特朗普:我可能飞过去
  • 中美大幅下调超100%关税,印巴四日“战争”复盘|907编辑部
  • 中美发布日内瓦经贸会谈联合声明达成关税共识,外交部回应
  • 何立峰:中方坚定支持多边主义和自由贸易,支持世贸组织在全球经济治理中发挥更大作用