【设计模式】——工厂模式

news2024/12/26 22:52:56

什么是工厂模式?

Java的工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。这种类型的设计模式属于创建型模式,它提供了了一种创建对象的最佳方式。在Java中,工厂模式常常用于创建实例对象,例如通过一个工厂方法来创建对象,而不是直接使用new关键字。这样可以使代码更加灵活,易于扩展和修改。

为什么要有工厂模式?

很多人都会纠结于“既然都有了构造函数,何必再折腾那么多事情呢”。为了解答这个问题,先解释下构造函数是干什么用的。先用最早出现的C,创建资源差不多要这么干:some_struct * p =

(some_struct*)malloc(sizeof(some_struct)); init_some_struct§;
do_something§;

即先分配内存,再做类型转换,再初始化,然后使用。而在OOP的时代,创建一个对象是很频繁的事情。同时,一个没初始化的数据结构是无法使用的。因此,构造函数被发明出来,将分配内存+初始化合并到了一起。如C++的语法是:

SomeClz *p = new SomeClz(); do_something§; // or
p.do_something_else();

java也沿用了这个设计。但是,整个构造函数完成的工作从更高层的代码设计角度还是太过于初级。因此复杂的创建逻辑还是需要写代码来控制。所以还是需要:

SomeClz * createSomeClz(…) { // 做一些逻辑 SomeClz *p = new SomeClz();
// 或者复用已经有的对象 // 再做一些额外的初始化 return p; }

这就是Factory的雏形。
引用来自知乎,作者:大宽宽

工厂模式的三种形态

简单工厂模式(Simple Factory)
工厂方法模式(Factory Method)
抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。 我们先从以下案例对工厂模式做个初步的了解:

(1)在没有工厂的时代,如果客户需要一款宝马车,那么就需要客户去创建一款宝马车,然后拿来用。

(2)简单工厂模式:后来出现了工厂,用户不再需要去创建宝马车,由工厂进行创建,想要什么车,直接通过工厂创建就可以了。比如想要320i系列车,工厂就创建这个系列的车。

(3)工厂方法模式:为了满足客户,宝马车系列越来越多,如320i、523i等等系列,一个工厂无法创建所有的宝马系列,于是又单独分出来多个具体的工厂,每个具体工厂创建一种系列,即具体工厂类只能创建一个具体产品。但是宝马工厂还是个抽象,你需要指定某个具体的工厂才能生产车出来。

(4)抽象工厂模式:随着客户要求越来越高,宝马车必须配置空调,于是这个工厂开始生产宝马车和需要的空调。最终是客户只要对宝马的销售员说:我要523i空调车,销售员就直接给他523i空调车了。而不用自己去创建523i空调车宝马车。
引用来自CSDN博主「张维鹏」的原创文章

具体实现

简单工厂模式

// 引入一个抽象类,声明其构造方法。
public abstract class SmartPhone {

    public SmartPhone(){

    }
}
// 引入HUAWEI类,集成手机类,并实现抽象方法
public class HUAWEI extends SmartPhone {

    public HUAWEI(){
        System.out.println("HUAWEI 666");
    }
}
// 引入IPHONE类,集成手机类,并实现抽象方法
public class IPHONE extends SmartPhone {

    public IPHONE(){
        System.out.println("IPHONE 666");
    }
}

这样,我们就有了两个类,都分别继承了手机类

// 创建工厂,PhoneFactory ,入参为1,创建实体华为。入参为2,创建实体苹果
public class PhoneFactory {
    public SmartPhone createPhone(int param){
        if(param == 1){
            return new HUAWEI();
        }
        if(param == 2){
            return new IPHONE();
        }
        else {
            return null;
        }
    }
}

运用工厂进行实例化:

public class AdminTest {
    public static void main(String[] args) {
        PhoneFactory phoneFactory = new PhoneFactory();
        SmartPhone phone = phoneFactory.createPhone(1);
    }
}

输出:
在这里插入图片描述

工厂方法模式

简单工厂模式的缺点就是,如果有很多个类都要继承手机类,那么工厂类的判断方法就会特别冗余。
所以我们有了工厂方法模式。

public  interface Factory {
    SmartPhone createSmartPhone();
}

public class HuaweiFactory implements Factory {

    @Override
    public SmartPhone createSmartPhone() {
        return new HUAWEI();
    }
}
public class IphoneFactory implements Factory {
    @Override
    public SmartPhone createSmartPhone() {
        return new IPHONE();
    }
}

运用:

public class AdminTest {
    public static void main(String[] args) {
       IphoneFactory iphoneFactory = new IphoneFactory();
       SmartPhone smartPhone = iphoneFactory.createSmartPhone();
    }
}

抽象工厂模式

我要创建很多,比如说生产电脑的同时,生产了显卡和cpu。
这时,我们引入抽象工厂模式的概念。
简单的讲,就是直接抽象工厂出来,而不是工厂生产的具体实例。

先创建三个接口,分别是电脑,显卡和cpu

public interface Computer {

    void makeGPU();

    void makeCPU();
}

public interface CPU {
    void makeCPU();
}

public interface GPU {
    void makeGPU();
}

显卡和cpu的实例

public class AMDCPU implements CPU {
    @Override
    public void makeCPU() {
        System.out.println("AMD YYDS!");
    }
}
public class IntelCPU implements CPU {
    @Override
    public void makeCPU() {
        System.out.println("INTEL 666!");
    }
}

public class AMDGPU implements GPU {
    @Override
    public void makeGPU() {
        System.out.println("AMD的显卡世界第一!");
    }
}
public class IntelGPU implements GPU {
    @Override
    public void makeGPU() {
        System.out.println("有钱人都买英特尔的显卡!");
    }
}

创建工厂类,分别实现amd或者Intel

public class AMDComputer implements Computer {
    @Override
    public void makeGPU() {
        AMDGPU amdgpu = new AMDGPU();
        amdgpu.makeGPU();
    }

    @Override
    public void makeCPU() {
        AMDCPU amdcpu = new AMDCPU();
        amdcpu.makeCPU();
    }
}
public class INTELComputer implements Computer {
    @Override
    public void makeGPU() {
        IntelGPU intelGPU = new IntelGPU();
        intelGPU.makeGPU();
    }

    @Override
    public void makeCPU() {
        IntelCPU intelGPU = new IntelCPU();
        intelGPU.makeCPU();
    }
}

通过抽象工厂创建电脑实例

public class AdminTest {
    public static void main(String[] args) {
        AMDComputer amdComputer = new AMDComputer();
        amdComputer.makeCPU();
        amdComputer.makeGPU();
    }
}

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

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

相关文章

替换开源LDAP,西井科技用宁盾目录统一身份,为业务敏捷提供支撑

客户介绍 上海西井科技股份有限公司成立于2015年,是一家深耕于大物流领域的人工智能公司,旗下无人驾驶卡车品牌Q-Truck开创了全球全时无人驾驶新能源商用车的先河,迄今为止已为全球16个国家和地区,120余家客户打造智能化升级体验…

houdini vex中的属性类型(attribute)

https://www.sidefx.com/docs/houdini/vex/snippets.html#parameters

【LUBAN】烧录经常失败怎么办?

目录 1、问题描述2、处理办法 1、问题描述 在一些PC上烧录时,经常出现烧录失败的问题(如下图所示),这是因为烧录时会重启USB口,而PC一些其它的程序占用了此USB口,导致数据传输失败。多试几次也是能成功的&…

c语言指针的运算

1、通过指针计算数组的元素&#xff08;指针相减&#xff0c;类型需要一致&#xff09;&#xff0c;比如数组元素指针相减得到的是中间相差的元素个数&#xff0c;可以用于计算数组元素的个数等 #include "stdio.h" #include <stdlib.h>int main() {int a[10]…

内卷化时代,一名普通测试员的铁饭碗究竟是什么?

内卷&#xff0c;是现在热度非常高的一个词汇&#xff0c;随着热度不断攀升&#xff0c;隐隐有了“万物皆可卷”的程度。究其来源&#xff0c;内卷这个词的出现&#xff0c;是伴随着996开始讨论的。很不幸&#xff0c;996、福报等等这些词的重灾区和源头就是计算机/互联网行业。…

学了一个礼拜 JavaScript 为什么还是学不会?

前言 首先从你的描述里面我先以我的主观臆断来猜测一下你是没有任何编程的基础的&#xff0c;Js按理来说在各语言中并不是非常难学&#xff0c;当然如果你是纯新手入门&#xff0c;那么确实前期需要时间来沉淀一下语法&#xff0c;一个礼拜的话&#xff0c;按理来说应该是在沉…

JVM基础篇-StringTable

StringTable 特性 常量池中的字符串仅是符号&#xff0c;第一次用到时才变为对象 利用串池的机制&#xff0c;来避免重复创建字符串对象 字符串变量拼接的原理是 StringBuilder &#xff08;1.8&#xff09; 字符串常量拼接的原理是编译期优化 可以使用 intern 方法&#…

利用大数据分析工具,实现多场景可视化数据管理

官方使用文档 https://yanhuang.yuque.com/staff-sbytbc/rb5rur? 准备服务器环境 购买服务器 购买腾讯云服务器&#xff0c;1300 元新人价&#xff0c;一年时间 ●4核16G内存 ●CentOS 6.7 &#xff08;补充说明&#xff1a;最新的 2.7.1 GA 版本&#xff0c;8G 内存也是可以…

TCP的三次握手四次挥手

TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手&#xff1a;为了对每次发送的数据量进行跟踪与协商&#xff0c;确保数据段的发送和接收同步&#xff0c;根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系&#xff0c;并建立虚连接。 四次挥手&a…

flyway快速入门

flyway快速入门 一、flyway是什么&#xff1f;二、flyway使用目的1. 使用原因&#xff1a;2. 举个例子&#xff1a; 三、flyway工作原理四、flyway使用约定和命名规则1. 数据库版本文件整体约定2. 数据库版本文件夹管理约定3. 数据库版本文件命名约定4. 禁止项 五、flyway配置和…

微信多开(双开三开均可,且不局限于微信,其他设备亦可)

1.鼠标右键“微信”&#xff0c;属性 如上图&#xff0c;自动选取的&#xff0c;别动&#xff0c;然后CtrlC,,,,结果如下 "C:\Program Files (x86)\Tencent\WeChat\WeChat.exe" 2.创建文本&#xff0c;电脑桌面空白处单击&#xff0c;新建&#xff0c;文本档案&#…

Java版工程行业管理系统源码-专业的工程管理软件-em提供一站式服务 em

​ Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目…

安卓:BottomNavigationBar——底部导航栏控件

目录 一、BottomNavigationBar介绍 二、BottomNavigationBar的常用方法及其常用类 &#xff08;一&#xff09;、常用方法 1. 添加菜单项 2. 移除菜单项 3. 设置选中监听器 4. 设置当前选中项 5. 设置徽章 6. 样式和颜色定制 7. 动画效果 8. 隐藏底部导航栏。 9、设…

局域网新大陆?

操作后&#xff0c;即可实现局域网互通。

【java】民营医院、门诊部、连锁集团、公立医疗云HIS系统源码

基于云计算技术的B/S架构的医院管理系统(简称云HIS)&#xff0c;为医疗机构提供标准化的、信息化的、高效可靠的医疗信息管理系统&#xff0c;实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。利用云计算平台的技术优势&#xff0c;建立统一的云HIS、云病历、云P…

性能监控工具-Grafana安装和使用方法

Grafana是一款开源的数据可视化和监控平台。它提供了丰富的可视化方式&#xff0c;如图表、仪表盘、警报等&#xff0c;支持多种数据源&#xff0c;包括Prometheus、InfluxDB、Graphite等&#xff0c;适用于各种规模的系统监控和数据分析。Grafana还有一个强大的插件生态系统&a…

视频监控汇聚平台EasyCVR视频分享页面WebRTC流地址播放不了是什么原因?

开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多…

淘宝店铺数据API接口 店铺详情数据API 店铺所有商品API接口

引言 在电商平台上&#xff0c;店铺所有商品API接口是一项非常重要且有着广泛应用的技术。它使得开发者能够方便地获取和管理店铺中的所有商品信息&#xff0c;进而实现自动化的商品管理和数据分析。本文将详细介绍店铺所有商品API接口的定义、功能以及调用流程&#xff0c;并附…

王道《操作系统》学习(二)——进程管理(三)

2.3.1 进程同步、进程互斥 &#xff08;1&#xff09;进程同步 &#xff08;2&#xff09;进程互斥 “同时”指的是宏观上的同时&#xff0c;微观上可能这些进程是交替地在访问这些共享资源的 当“上锁”后&#xff0c;其他的进程想要访问临界资源时&#xff0c;在进入区进行检…

js修改png图片颜色

思路是利用canvas 改变图片颜色 /*** 将png图片转成目标颜色* param imgUrl 可传入图片URL 或者 Base64* param RGBArr 要换成的目标颜色RGB 数组格式[R,G,B]* param Functon callback回调*/ function changeImageColor(imgUrl, RGBArr, callback) {let image new Image();im…