【简单理解什么是简单工厂、工厂方法与抽象工厂模式】

news2025/4/18 12:15:05

一、简单工厂模式
1.简单工厂模式 通过一个工厂类集中管理对象的创建 ,通过参数决定具体创建哪个对象。
#适合对象类型较少且变化不频繁的场景,缺点是违反开闭原则(新增产品需修改工厂类)

开闭原则(对扩展开放‌+对修改关闭‌) :当有新的需求或变化时,可以通过增加新的模块或功能来扩展软件实体的行为,而不需要修改现有的代码。;软件实体一旦被创建并投入使用,其内部实现应该保持稳定,不应轻易修改。

  1. 实现步骤:
    定义产品接口——>实现具体产品类——>创建工厂类——>通过参数控制对象创建

示例代码:

// 1. 定义产品接口
interface Car {
    void drive();
}

// 2. 具体产品实现
class Tesla implements Car {
    @Override
    public void drive() {
        System.out.println("Driving Tesla!");
    }
}

class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("Driving BMW!");
    }
}

// 3. 使用枚举优化参数
enum CarType {
    TESLA, BMW
}

class CarFactory {
    public static Car createCar(CarType type) {
        switch (type) {
            case TESLA:
                return new Tesla();
            case BMW:
                return new BMW();
            default:
                throw new IllegalArgumentException("Unknown car type!");
        }
    }
}

// 4. 使用
public class Main {
    public static void main(String[] args) {
        Car tesla = CarFactory.createCar(CarType.TESLA);
        tesla.drive(); // Driving Tesla!
        Car bmw = CarFactory.createCar(CarType.BMW);
        bmw.drive(); // Driving BMW!
    }
}

二、工厂方法模式

  1. 工厂方法模式通过定义一个抽象工厂接口,由子类(具体工厂)决定创建哪个具体产品。符合开闭原则,新增产品只需新增工厂类,无需修改原有代码。
  2. 扩展性强,新增产品类型时只需添加新工厂和产品类。解耦客户端与具体产品,客户端只需依赖抽象工厂接口。
  3. 工厂方法模式的实现步骤:定义产品接口——>定义产品的具体实现类,让其实现"产品接口"并重写"产品接口方法"——>定义产品的工厂接口——>定义产品具体的工厂类,让其实"现工厂接口"并重写"工厂接口方法"——>在使用的时候需要创建不同产品的工厂类对象,然后调用他们重写后的接口方法来创建对象。

示例代码

// 1. 定义产品接口
interface Phone {
    void call();
}

// 2. 具体产品实现
class iPhone implements Phone {
    @Override
    public void call() {
        System.out.println("Calling with iPhone!");
    }
}

class Samsung implements Phone {
    @Override
    public void call() {
        System.out.println("Calling with Samsung!");
    }
}

// 3. 定义工厂接口
interface PhoneFactory {
    Phone createPhone();
}

// 4. 具体工厂实现
class iPhoneFactory implements PhoneFactory {
    @Override
    public Phone createPhone() {
        return new iPhone();
    }
}

class SamsungFactory implements PhoneFactory {
    @Override
    public Phone createPhone() {
        return new Samsung();
    }
}

// 5. 使用
public class Main {
    public static void main(String[] args) {
        PhoneFactory iphoneFactory = new iPhoneFactory();
        Phone iphone = iphoneFactory.createPhone();
        iphone.call(); // Calling with iPhone!
        
        PhoneFactory samsungFactory = new SamsungFactory();
        Phone samsung = samsungFactory.createPhone();
        samsung.call(); // Calling with Samsung!
    }
}

三、抽象工厂模式

  1. 抽象工厂模式用于创建一组相关或依赖的对象(如不同品牌的手机 + 耳机)。适用于产品族的创建,而不是单个产品。

  2. 定义与特点
    定义:抽象工厂模式用于创建一组相关或依赖的对象(如不同品牌的手机 + 耳机)。
    适用场景:需要创建“产品族”的场景(如苹果全家桶、三星全家桶)。
    核心思想:抽象工厂接口定义多个工厂方法,每个方法对应一个产品类型。

  3. 实现步骤
    定义产品族接口(如Phone和Earphones)——>实现具体产品类(分属不同产品族)——>定义抽象工厂接口,包含多个工厂方法——> 实现具体工厂类,为每个产品族提供创建逻辑

示例代码:

// 1. 定义产品族接口
interface Phone {
    void call();
}

interface Earphones {
    void listen();
}

// 2. 具体产品实现(苹果产品族)
class iPhone implements Phone {
    @Override
    public void call() {
        System.out.println("Calling with iPhone!");
    }
}

class AirPods implements Earphones {
    @Override
    public void listen() {
        System.out.println("Listening with AirPods!");
    }
}

// 3. 具体产品实现(三星产品族)
class SamsungPhone implements Phone {
    @Override
    public void call() {
        System.out.println("Calling with Samsung!");
    }
}

class SamsungEarphones implements Earphones {
    @Override
    public void listen() {
        System.out.println("Listening with Samsung Earphones!");
    }
}

// 4. 定义抽象工厂接口
interface TechFactory {
    Phone createPhone();
    Earphones createEarphones();
}

// 5. 具体工厂实现(苹果工厂)
class AppleFactory implements TechFactory {
    @Override
    public Phone createPhone() {
        return new iPhone();
    }

    @Override
    public Earphones createEarphones() {
        return new AirPods();
    }
}

// 6. 具体工厂实现(三星工厂)
class SamsungFactory implements TechFactory {
    @Override
    public Phone createPhone() {
        return new SamsungPhone();
    }

    @Override
    public Earphones createEarphones() {
        return new SamsungEarphones();
    }
}

// 7. 使用
public class Main {
    public static void main(String[] args) {
        TechFactory appleFactory = new AppleFactory();
        appleFactory.createPhone().call();      // Calling with iPhone!
        appleFactory.createEarphones().listen(); // Listening with AirPods!
        
        TechFactory samsungFactory = new SamsungFactory();
        samsungFactory.createPhone().call();      // Calling with Samsung!
        samsungFactory.createEarphones().listen(); // Listening with Samsung Earphones!
    }
}

四、模式对比与疑问解答

  1. 工厂方法模式中选择接口而非抽象类的原因
    答案:
    灵活性更高:接口支持多实现,Java 不支持多继承,但类可实现多个接口。抽象类可能包含默认实现,限制子类灵活性。
    符合开闭原则:新增产品(如 Xiaomi)只需添加新具体产品类和对应工厂类,无需修改原有代码。
    设计意图契合:工厂方法模式的核心是定义“创建对象的接口”,而接口仅定义方法签名,不提供具体实现。
  2. 三种模式的核心区别
特性简单工厂模式工厂方法模式抽象工厂模式
创建对象类型单一产品的不同实现(不同汽车)单一产品的不同实现(不同手机)一组相关产品(手机 + 耳机)
工厂结构单一工厂类(静态方法)抽象工厂接口 + 具体工厂类抽象工厂接口 + 具体工厂类
工厂方法数量1 个(createCar)1 个(createPhone)多个(如 createPhone 和 createEarphones)
扩展性新增产品需修改工厂类新增产品只需添加新工厂类新增产品族需添加新工厂类
是否符合开闭原则不符合符合符合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2332804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HOW - React Developer Tools 调试器

目录 React Developer Tools使用Components 功能特性1. 查看和编辑 props/state/hooks2. 查找组件3. 检查组件树4. 打印组件信息5. 检查子组件 Profiler 功能特性Commit ChartFlame Chart 火焰图Ranked Chart 排名图 why-did-you-render 参考文档: React调试利器&a…

STM32F103C8T6单片机开发:简单说说单片机的外部GPIO中断(标准库)

目录 前言 如何使用STM32F1系列的标准库完成外部中断的抽象 初始化我们的GPIO为输入的一个模式 初识GPIO复用,开启GPIO的复用功能时钟 GPIO_EXTILineConfig和EXTI_Init配置外部中断参数 插入一个小知识——如何正确的配置结构体? 初始化中断&#…

docker的安装使用0废话版本自学软硬件工程师778天

见字如面, 这里是AIGC创意人_竹相左边 上一篇 因为 自己开发客户系统,为了解决一键启动 前端后端,涉及到了docker-compose 在新的电脑上安装docker 有各种问题这里再次记录下,既是笔记也是分享。 我先用自己的话说一遍&#xff0…

探秘 Svelte+Vite+TS+Melt - UI 框架搭建,开启高效开发

框架太“重”了:通常一个小型项目只由少数几个简单页面构成,如果使用 Vue 或者 React 这些框架来研发的话,有点“大材小用”了。构建的产物中包含了不少框架运行时代码(虚拟 DOM、响应式、状态管理等),这些代码对于小型项目而言是…

vscode 连不上 Ubuntu 18 server 的解决方案

下载 vscode 历史版本 18.5(windows请装在 系统盘 C 盘) 打开 vdcode,将 自动更新 设置为 None (很关键,否则容易前功尽弃) 重命名(删除) 服务器上的 .vscode-server 文件夹 重新…

云原生运维在 2025 年的发展蓝图

随着云计算技术的不断发展和普及,云原生已经成为了现代应用开发和运维的主流趋势。云原生运维是指在云原生环境下,对应用进行部署、监控、管理和优化的过程。在 2025 年,云原生运维将迎来更加广阔的发展前景,同时也将面临着一系列…

Redis进阶--哨兵

目录 一、引言 二、介绍 三、哨兵的核心功能 四、使用docker进行单个主机redis主从复制哨兵操作 五、哨兵重新选取主节点的流程 1.主观下线 2.客观下线 3.主节点挂了 4.挑选新主节点 六、总结 一、引言 如果主从复制中,主节点挂了,从节点会迷茫…

Franka 机器人x Dexterity Gen引领遥操作精细任务新时代

教授机器人工具灵活操作难题 在教授机器人灵活使用工具方面,目前主要有两种策略:一是人类遥控(用于模仿学习),二是模拟到现实的强化学习。然而,这两种方法均存在明显的局限性。 1、人类遥控(用…

专题|MATLAB-R语言Logistic逻辑回归增长模型在互联网金融共生及移动通信客户流失分析实例合集

全文链接:https://tecdat.cn/?p41343 作为数据科学家,我们始终关注如何通过模型创新揭示复杂系统的动态规律。本专题合集聚焦两大核心应用场景,通过 Logistic 增长模型与逻辑回归技术,为互联网金融共生演化与移动通信客户流失预警…

【学生管理系统升级版】

学生管理系统升级版 需求分析:注册功能:登录功能:验证码规则:忘记密码: 实操:系统主页面注册功能登录功能忘记密码效果演示 需求 为学生管理系统书写一个登陆、注册、忘记密码的功能。     只有用户登录成功之后&…

Web3 的云基础设施正在成型,Polkadot 2.0 用三项技术改写“上链成本”

在Web3基础设施内卷加剧的今天,“如何以更低成本、更大灵活性部署一条高性能应用链”正成为开发者们最关心的问题。而刚刚走出“技术慢热”误区的Polkadot,正在用一套名为 Polkadot 2.0 的架构升级方案,重新定义这一问题的解法。 这套升级最…

机器学习——ROC曲线、PR曲线

一、ROC曲线简介 1.1 ROC曲线的构成 1.横轴(假正率,FPR): 表示负样本被错误分类为正的比例(越小越好) 2.纵轴(真正率,TPR,即召回率): 表示正样…

我为女儿开发了一个游戏网站

大家好,我是星河。 自从协助妻子为女儿开发了算数射击游戏后,星河就一直有个想法:为女儿打造一个专属的学习游戏网站。之前的射击游戏虽然有趣,但缺乏难度分级,无法根据女儿的学习进度灵活调整。而且,仅仅…

【Spring Cloud Netflix】GateWay服务网关

1.基本概述 GateWay用于在微服务架构中提供统一的入口点,对请求进行路由,过滤和处理。它就像是整个微服务系统的大门,所有外部请求都要通过它才能访问到后端的各个微服务。 2.核心概念 2.1路由(Route) 路由是Spring Cloud gateWay中最基本…

Docker部署Jenkins服务

文章目录 1.下载Jenkins服务2.部署Java21(可选)2.1 安装Java21 3.Maven3.9.9安装4.启动Jenkins5.初始化Jenkins5.1 入门5.2 安装推荐的插件5.3 创建第一个管理员用户5.4 实例配置5.5 Jenkins已就绪5.6 开始使用Jenkins5.7 重启Jenkins 6.配置Jenkins6.1 …

[ctfshow web入门] web40

信息收集 怎么一下子多这么多过滤啊,我以为跳过了好几题 这又能eval了,但是连$也不能用了 不能用. * ?,所以打不出fla*或者fla?????了 不能用/,构造不出日志注入和伪协议包含 仔细观察,禁的是中文的括号&#x…

蓝桥杯c ++笔记(含算法 贪心+动态规划+dp+进制转化+便利等)

蓝桥杯 #include <iostream> #include <vector> #include <algorithm> #include <string> using namespace std; //常使用的头文件动态规划 小蓝在黑板上连续写下从 11 到 20232023 之间所有的整数&#xff0c;得到了一个数字序列&#xff1a; S12345…

Qt问题之 告别软件因系统默认中文输入法导致错误退出的烦恼

1. 问题 使用Qt进行研发时&#xff0c;遇到一个问题&#xff0c;当在系统默认输入法中文&#xff08;英文输入法或者搜狗就不会触发闪退&#xff09;的情况下&#xff0c;选中QTableWidget控件&#xff08;QTableWidgetItem有焦点&#xff0c;但是不双击&#xff09;&#xff…

AlDente Pro for Mac电脑 充电限制保护工具

AlDente Pro for Mac电脑 充电限制保护工具 一、介绍 AlDente Pro for Mac&#xff0c;是一款充电限制保护工具&#xff0c;是可以限制最大充电百分比来保护电池的工具。锂离子和聚合物电池&#xff08;如 MacBook 中的电池&#xff09;在40&#xff05; 至 80&#xff05; 之…

算法训练之动态规划(一)

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…