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

【设计模式】-工厂模式(简单工厂、工厂方法、抽象工厂)

工厂模式(简单工厂、工厂方法、抽象工厂)

介绍

简单工厂模式

简单工厂模式不属于23种GoF设计模式之一,但它是一种常见的设计模式。它提供了一种创建对象的接口,但由子类决定要实例化的类是哪一个。这样,工厂方法模式让类的实例化推迟到子类。

  • 优点:允许客户端通过一个共同的接口来创建对象,隐藏了实例化的过程。

  • 缺点:新增产品时需要修改工厂代码违反开闭原则

  • 框架应用
    JDBCDriverManager根据数据库 URL 返回对应的 Connection 对象

工厂方法模式(Factory Method Pattern)

工厂方法模式定义了一个用于创建对象的接口,但是让子类决定实例化哪个类。工厂方法使得一个类的实例化延迟到其子类。

  • 优点:符合开闭原则,可以在不修改工厂的情况下增加新的产品。

  • 缺点:每增加一种产品,就需要增加相应的具体工厂类,增加了系统的复杂度
    简单工厂模式相比于工厂方法模式比较简单,管理不太复杂,所以在很多项目中也不会完全设计原则编写代码,很多地方还是采用了简单工厂模式

  • 框架应用
    SpringBeanFactory:通过 ApplicationContext(子类)动态创建和管理 Bean
    MyBatisSqlSessionFactory负责创建SqlSession实例,这里的SqlSessionFactory就是一个典型的工厂角色。

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式提供了一组接口,用于创建相关或依赖对象的家族,而不需要明确指定具体的类。它是工厂方法模式的进一步扩展。

  • 优点:可以很容易地在一组相关的产品中切换实现(产品族)。
  • 缺点:当产品族中加入新产品时,所有工厂类都需要修改(在产品族数量长期稳定的时候建议使用)。

代码实现

简单工厂模式

在这个例子中,我们将创建一个简单的工厂用于生成不同品牌的汽车实例。

// 汽车接口
interface Car {
    void drive();
}

// 宝马汽车
class BMW implements Car {
    public void drive() {
        System.out.println("Driving a BMW.");
    }
}

// 奔驰汽车
class Mercedes implements Car {
    public void drive() {
        System.out.println("Driving a Mercedes.");
    }
}

// 简单汽车工厂
class SimpleCarFactory {
    public static Car createCar(String type) {
        if ("BMW".equalsIgnoreCase(type)) {
            return new BMW();
        } else if ("Mercedes".equalsIgnoreCase(type)) {
            return new Mercedes();
        }
        return null;
    }
}

// 客户端代码
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        Car car = SimpleCarFactory.createCar("BMW");
        if (car != null) {
            car.drive();
        }
    }
}
类图

在这里插入图片描述

工厂方法模式

这里,我们将使用工厂方法模式,每个具体的工厂负责创建特定类型的汽车。

// 汽车接口
interface Car {
    void drive();
}

// 宝马汽车
class BMW implements Car {
    public void drive() {
        System.out.println("Driving a BMW.");
    }
}

// 奔驰汽车
class Mercedes implements Car {
    public void drive() {
        System.out.println("Driving a Mercedes.");
    }
}

// 抽象工厂接口
interface CarFactory {
    Car createCar();
}

// 宝马工厂
class BMWFactory implements CarFactory {
    public Car createCar() {
        return new BMW();
    }
}

// 奔驰工厂
class MercedesFactory implements CarFactory {
    public Car createCar() {
        return new Mercedes();
    }
}

// 客户端代码
public class FactoryMethodDemo {
    public static void main(String[] args) {
        CarFactory factory = new BMWFactory();
        Car car = factory.createCar();
        car.drive();
    }
}
类图

在这里插入图片描述

抽象工厂模式

在抽象工厂模式的例子中,我们将创建一个家族的产品(比如汽车及其配件)。

// 抽象产品A - 车身
interface Body {
    void design();
}

// 具体车身A1 - 宝马车身
class BMWBody implements Body {
    public void design() {
        System.out.println("Designing BMW body.");
    }
}

// 具体车身A2 - 奔驰车身
class MercedesBody implements Body {
    public void design() {
        System.out.println("Designing Mercedes body.");
    }
}

// 抽象产品B - 引擎
interface Engine {
    void build();
}

// 具体引擎B1 - 宝马引擎
class BMWEngine implements Engine {
    public void build() {
        System.out.println("Building BMW engine.");
    }
}

// 具体引擎B2 - 奔驰引擎
class MercedesEngine implements Engine {
    public void build() {
        System.out.println("Building Mercedes engine.");
    }
}

// 抽象工厂
interface CarFactory {
    Body createBody();
    Engine createEngine();
}

// 宝马工厂
class BMWFactory implements CarFactory {
    public Body createBody() { return new BMWBody(); }
    public Engine createEngine() { return new BMWEngine(); }
}

// 奔驰工厂
class MercedesFactory implements CarFactory {
    public Body createBody() { return new MercedesBody(); }
    public Engine createEngine() { return new MercedesEngine(); }
}

// 客户端代码
public class AbstractFactoryDemo {
    public static void main(String[] args) {
        CarFactory factory = new BMWFactory();
        Body body = factory.createBody();
        Engine engine = factory.createEngine();
        body.design();
        engine.build();
    }
}
类图

在这里插入图片描述
上述代码展现了如何使用不同的设计模式来创建宝马和奔驰品牌的汽车。每种模式都有其独特的应用场景,可以根据具体需求选择最合适的模式。

相关文章:

  • flask和django的对比
  • ECCV2022 | LGV | LGV:利用大几何邻域提升对抗样本的可迁移性
  • Vue2组件通信
  • 工作流改造:从一到千
  • 网络安全用centos干嘛 网络安全需要学linux吗
  • DBSCAN 基于密度的空间带噪聚类法
  • LM Studio纯CPU运行大模型不如ollama效率高
  • jenkins服务启动-排错
  • 数组_二分查找
  • Android-构建问题记录
  • Java版PDF拼接
  • 配查查:解锁商业奥秘,赋能智慧决策
  • OpenEuler学习笔记(三十二):在OpenEuler上搭建项目管理平台
  • django静态文件配置
  • Neo4j OGM学习和体验
  • Linux中安装open-webui报sqlite版本低的解决办法
  • 【React组件通讯双重视角】函数式 vs 类式开发指南
  • 第二章:基础概念精讲 - 第二节 - Tailwind CSS 颜色系统和主题定制
  • 什么是环形分区光源
  • Edge浏览器清理主页
  • 左手免费午餐右手花开岭,邓飞14年公益之路的中国贡献
  • 被围观的“英之园”,谁建了潮汕天价违建?
  • 上市公司重大资产重组新规九要点:引入私募“反向挂钩”,压缩审核流程
  • 德州国资欲退出三东筑工,后者大股东系当地房企东海集团
  • 端午小长假前夜火车票今日开抢,多个技巧提高购票成功率
  • 共建医学人工智能高地,上海卫健委与徐汇区将在这些方面合作