设计模式三:工厂模式

news2025/1/16 5:12:57

工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式,其中后两者属于23中设计模式

各种模式中共同用到的实体对象类:

//汽车类:宝马X3/X5/X7;发动机类:B48TU、B48
    
//宝马汽车接口
public interface BMWCar {
    void show();
}

//发动机接口
public interface Engine {
    void show();
}

//宝马X3
public class BMWX3 implements BMWCar {
    @Override
    public void show() {
        System.out.println("华晨宝马X3:39.96-48.69万");
    }
}

//宝马X5
public class BMWX5 implements BMWCar {
    @Override
    public void show() {
        System.out.println("华晨宝马X5:58.75-80万");
    }
}

//宝马X7
public class BMWX7 implements BMWCar {
    @Override
    public void show() {
        System.out.println("华晨宝马X3:89.35-102.25万");
    }
}

//B48TU发动机
public class B48TUEngine implements Engine {
    @Override
    public void show() {
        System.out.println("B48TU:涡轮增压 压缩比 11:1");
    }
}

//B48发动机
public class B48Engine implements Engine {
    @Override
    public void show() {
        System.out.println("B48:涡轮增压 压缩比 10.2:1");
    }
}

1、简单工厂模式

  • 模型

​ 用户只需要使用汽车生产工厂,告诉其想要生产的车型,具体生产细节不需要了解即可得到希望车型
在这里插入图片描述

  • 实现
//简单工厂类
public class BMWCarFactory {
    public static BMWCar buy(String carName){
        switch (carName){
            case "BMWX5":
                return new BMWX5();
            case "BMWX3":
                return new BMWX3();
            default:
                return null;
        }
    }
}

//测试
public class Consumer {
    public static void main(String[] args) {
        BMWCar bmwCar = BMWCarFactory.buy("BMWX5");
        if (bmwCar == null){
            System.out.println("无该车型");
        }
        assert bmwCar != null;
        bmwCar.show();
    }
}

简单工厂模式:

再添加一个宝马产品,就要修改factory类

1、使用进阶版简单工厂模式

2、使用工厂方法模式,即有自工厂生产对应车型,X5由X5Factory生产,X3由X3Factory生产,在添加一种车型,则对应添加一个工厂类型

简单工厂模式适用于的场景:

1、适用 于工厂类负责创建的对象较少的场景,

2、且客户端只需要传入工厂类的参数,对于如何创 建对象的逻辑不需要关心。

简单工厂模式缺点:

1、工厂类的职业相对过重,增加新的产品时需要修改工厂类的判断逻辑,违背开闭原则

2、不易于扩展过于复杂的产品结构

2、进阶版简单工厂模式

//工厂类
public class BMWFactory {
    public static <T> T buy(Class<T> clazz){
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            return null;
        }
    }
}

//测试
public class Consumer {
    public static void main(String[] args) {
        BMWCar newCar = BMWFactory.buy(BMWX3.class);
        if (newCar == null){
            System.out.println("无该车型");
        }
        newCar.show();
    }
}

3、工厂方法模式

  • 模型
    在这里插入图片描述
//宝马工厂接口
public interface BMWCarFactory {
    BMWCar buy();
}

//BMWX3工厂
public class BMWX3CarFactory implements BMWCarFactory {
    @Override
    public BMWCar buy() {
        //可在这里做一定处理,对客户不可见,即对客户是透明的
        //......
        return new BMWX3();
    }
}

//BMWX5工厂
public class BMWX5CarFactory implements BMWCarFactory {
    @Override
    public BMWCar buy() {
        //可在这里做一定处理,对客户不可见,即对客户是透明的
        //......
        return new BMWX5();
    }
}

//BMWX7工厂
public class BMWX7CarFactory implements BMWCarFactory {
    @Override
    public BMWCar buy() {
        //可在这里做一定处理,对客户不可见,即对客户是透明的
        //......
        return new BMWX7();
    }
}

//测试
public class Consumer {
    public static void main(String[] args) {
        BMWCar bmwCar = BMWCarFactory.buy("BMWX5");
        if (bmwCar == null){
            System.out.println("无该车型");
        }
        assert bmwCar != null;
        bmwCar.show();
    }
}

工厂方法模式的适用场景:

1、创建对象需要大量重复的代码

2、客户端(应用层)不依赖于产品类实例如何被创建、实现等细节,一个类通过其子类来指定创建哪个对象。

工厂方法模式的优点:

1、用户只关系所需产品对应的工厂,无须关心创建细节。

2、加入新产品符合开闭原则,提高了系统的可扩展性。

工厂方法模式的缺点:

1、类的个数容易过多,增加了代码结构的复杂度。

2、增加了系统的抽象性和理解难度。

工厂方法模式:

如果处了汽车之外,新增加发动机产品 B48TU发动机(X5搭载) 和 B48发动机(X3搭载)

那么需要新增发动机工厂接口、B48TU工厂、B48工厂、发动机接口、B48TU发动机、B48发动机

如下图所示
在这里插入图片描述

4、抽象工厂模式

  • 模型

在这里插入图片描述

  • 实现
//宝马工厂接口
public interface BMWFactory {
    BMWCar buyCar();
    Engine buyEngine();
}

//宝马X3工厂
public class BMWX3Factory implements BMWFactory {
    @Override
    public BMWCar buyCar() {
        return new BMWX3();
    }

    @Override
    public Engine buyEngine() {
        return new B48Engine();
    }
}

//宝马X5工厂
public class BMWX5Factory implements BMWFactory {
    @Override
    public BMWCar buyCar() {
        return new BMWX5();
    }

    @Override
    public Engine buyEngine() {
        return new B48TUEngine();
    }
}

//测试
public class Consumer {
    public static void main(String[] args) {
        BMWFactory factory = new BMWX3Factory();

        factory.buyCar().show();
        factory.buyEngine().show();
    }
}

抽象工厂模式:

将不同种类,同一等级的类放在一个工厂加工

但是新增产品时需要修改工厂类

抽象工厂模式使用场景:

1、客户端(应用层)不依赖于产品类实例如何被创建,实现等细节。

2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码。

3、提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体的实现。

抽象工厂模式优点:

1、具体产品在应用层代码隔离,无须关系创建细节。

2、将一个系列的产品族统一到一起创建。

抽象工厂模式缺点:

1、规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口。

2、增加了系统的抽象性和理解难度。

5、spring中的工厂模式

Calendar.getInstance()   //简单工厂模式
LoggerFactory、BeanFactory、FactoryBean   //工厂方法模式
Calendar
if (aLocale.hasExtensions()) {
    String caltype = aLocale.getUnicodeLocaleType("ca");
    if (caltype != null) {
        switch (caltype) {
            case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                break;
            case "japanese":
                cal = new JapaneseImperialCalendar(zone, aLocale);
                break;
            case "gregory":
                cal = new GregorianCalendar(zone, aLocale);
                break;
        }
    }
}
BeanFactory
public class TestBeanFactory {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // bean 的定义(class, scope, 初始化, 销毁)
        AbstractBeanDefinition beanDefinition =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config", beanDefinition);

        // 给 BeanFactory 添加一些常用的后处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        // 打印BeanFactory中Bean
        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }

    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);

        public Bean1() {
            log.debug("构造 Bean1()");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }
    }

    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            log.debug("构造 Bean2()");
        }
    }
}

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

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

相关文章

CSS-基础-MDN文档学习笔记

CSS构建基础 查看更多学习笔记&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官网 CSS选择器 选择器是什么 CSS 选择器是 CSS 规则的第一部分&#xff0c;它用来选择HTML元素&#xff0c;选择器所选择的元素&#xff0c;叫做选择器的对象 选择器列表 如果有多…

盘点3款实用的音频文件转文字工具!

在信息爆炸的时代&#xff0c;我们每天都面临着海量的信息输入和输出。其中&#xff0c;音频信息作为一种重要的信息传播方式&#xff0c;如何高效地将其转化为文字&#xff0c;成为许多人和企业迫切的需求。本文将为您盘点几款实用的音频转文字工具&#xff0c;让声音瞬间转化…

通过闭包表解决无限极代理分销

闭包表设计 闭包表是解决分层存储一个简单而又优雅的解决方案&#xff0c;它记录了表中所有的节点关系&#xff0c;并不仅仅是直接的父子关系。   在闭包表的设计中&#xff0c;额外创建了一张节点关系表(空间换取时间)&#xff0c;它包含两列&#xff0c;每一列都是一个指向…

facebook群控如何做?使用静态住宅ip代理有什么好处?

在进行Facebook群控时&#xff0c;ip地址的管理是非常重要的&#xff0c;因为Facebook通常会检测ip地址的使用情况&#xff0c;如果发现有异常的使用行为&#xff0c;比如从同一个ip地址频繁进行登录、发布内容或者在短时间内进行大量的活动等等&#xff0c;就会视为垃圾邮件或…

我的NPI项目之Android USB 系列(一) - 遥望和USB的相识

和USB应该是老朋友了&#xff0c;从2011年接触Android开发开始&#xff0c;就天天和USB打交道了。那时候还有不 对称扁头的usb/方口的usb&#xff0c;直到如今使用广泛的防反插USB3.0 type-C。 但是&#xff0c;一直有一个不是很清楚的问题萦绕在心头&#xff0c;那就是。先有…

Vue3 学习笔记(Day1)

「写在前面」 本文为尚硅谷禹神 Vue3 教程的学习笔记。本着自己学习、分享他人的态度&#xff0c;分享学习笔记&#xff0c;希望能对大家有所帮助。 目录 0 课程介绍 1 Vue3 简介 2 创建 Vue3 工程 2.1 基于 vue-cli 创建 2.2 基于 vite 创建&#xff08;推荐&#xff09; 2.3 …

[word] word正反面打印应该怎么设置呢? #知识分享#学习方法#职场发展

word正反面打印应该怎么设置呢&#xff1f; word文档打印时&#xff0c;如果页数比较多&#xff0c;出于格式要求或为了节省纸张&#xff0c;通常需要正反面打印&#xff0c;那怎么操作正反双面打印呢&#xff1f;通常有两种方法打印。 1、选择“打印”对话框底部的“打印”下…

linux 安装、删除 JTAG驱动

安装 安装驱动需要sudo访问权限&#xff0c;所以得手动安装。 在petalinux安装目录下&#xff1a; 文件的路径。 cd tools/xsct/data/xicom/cable_drivers/lin64/install_script/install_drivers 然后执行文件 install_drivers。 sudo ./install_drivers安装成功。 删除 …

FFmpeg进阶-给视频添加马赛克效果

很多时候为了隐藏视频中的敏感信息如人脸、身份证号、车牌号等,我们会采用马赛克算法对视频帧中的一部分内容进行处理。这里介绍一下如何采用FFmpeg实现马赛克效果。 马赛克效果算法的原理如下: 1.分块处理:首先将图像划分为多个小块或区域 2.像素替换:对于每个小块,算法会将…

sentinel的资源数据指标是如何采集

资源数据采集 之前的NodeSelectorSlot和ClusterBuilderSlot已经完成了对资源调用树的构建, 现在则是要对资源进行收集, 核心点就是这些资源数据是如何统计 LogSlot 作用: 记录异常请求日志, 用于故障排查 public class LogSlot extends AbstractLinkedProcessorSlot<Def…

鸿蒙 状态管理-组件装饰器

前提&#xff1a;基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。&#xff08;或有偏颇&#xff0c;自行斟酌&#xff09; 1.概念 Android中使用过Jetpack MVVM框架知道状态管理&#xff0c;包括React前端所使用的状态管理框架&#xff0c;都有所设…

爬虫知识--01

爬虫介绍 # 爬虫的概念&#xff1a; 通过编程技术(python:request,selenium)&#xff0c;获取互联网中的数据(app&#xff0c;小程序&#xff0c;网站)&#xff0c;数据清洗(xpaht&#xff0c;lxml)后存到库中(mysql&#xff0c;redis&#xff0c;文件&#xff0c;excel&#x…

GIN框架介绍以及使用

Gin是一个用Go语言编写的web框架。它是一个类似于martini但拥有更好性能的API框架, 由于使用了httprouter&#xff0c;速度提高了近40倍。 如果你是性能和高效的追求者, 你会爱上Gin&#xff0c;而且现在大多数企业都在使用Gin框架&#xff0c;反正学一学总没有错。 1、 GIn框…

微信小程序-绑定数据并在后台获取它

如图 遍历列表的过程中需要绑定数据&#xff0c;点击时候需要绑定数据 这里是源代码 <block wx:for"{{productList}}" wx:key"productId"><view class"product-item" bindtap"handleProductClick" data-product-id"{{i…

【J1939】一、概述,协议基础

文章目录 1. 背景2. 要点3. J1939帧细节3.1 协议数据单元(Protocol Data Unit,PDU)3.2 参数组编号(PGN)3.3 可疑参数编号(Suspect Parameter Number,SPN)参考1. 背景 J1939是一种用于商用车辆的通信协议,它定义了一套车辆电子控制单元之间进行数据通信的规范。J1939协议…

Java+SpringBoot:滑雪场管理的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

用CSS3画一个三角形

<style> .up{width:0;height:0;border: 100px solid transparent;border-top: 100px solid red;/*红色*/ } .down{width:0;height:0;border: 100px solid transparent;border-bottom: 100px solid blue;/*蓝色*/ } .left{width:0;height:0;border: 100px solid transpare…

各种手型都合适,功能高度可定制,雷柏VT9PRO mini和VT9PRO游戏鼠标上手

去年雷柏推出了一系列支持4KHz回报率的鼠标&#xff0c;有着非常敏捷的反应速度&#xff0c;在游戏中操作体验十分出色。尤其是这系列4K鼠标不仅型号丰富&#xff0c;而且对玩家的操作习惯、手型适应也很好&#xff0c;像是VT9系列就主打轻巧&#xff0c;还有专门针对小手用户的…

【动态规划专栏】专题一:斐波那契数列模型--------4.解码方法

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

Sora震撼发布:让你成为导演的时代终于到来!

关注【云原生百宝箱】公众号&#xff0c;获取更多云原生消息 OpenAI重磅发布了他们的视频生成大模型Sora&#xff0c;该模型可支持长达一分钟的高质量视频内容的生成&#xff0c;又着实又令人震惊了一把。 OpenAI朝着突破人类想象力的界限又迈出了一步&#xff0c;我相信你至少…