简单工厂模式抽象工厂模式

一.简单工厂模式

1.什么是工厂模式

工厂模式的核心就是把对象的生产过程交给工厂来完成,当外部需要一个对象时,由工厂提供接口来获取对象,这样一来即使生产对象的过程变了,仍然不影响外部对对象的获取和使用。

2.举个栗子

定义Chef(厨师),Coder(程序员)两个类。

/*** 厨师实体类*/
public class Chef {/*** 提供一个做事情的方法*/public void doSometing(){System.out.println("厨师正在烹调食物...");}
}
/***  程序员实体类*/
public class Coder {/*** 提供一个做事情的方法*/public void doSometing(){System.out.println("程序员正在编写程序...");}
}

如果我们要在其它地方使用这两个类,一般我们会这样做。

/*** 测试类*/
public class Test {public static void main(String[] args) {// 创建“厨师”对象Chef chef = new Chef();// 创建“程序员”对象Coder coder = new Coder();// 分别调用各自的操作方法chef.doSometing();coder.doSometing();}
}

感觉没有什么其它问题!现在新的需求来了。业务线需要在每个创建对象的地方加上日志,并且还要修改Coder的名字为UICoder,我们应该怎么做呢?假如有很多地方使用了上面创建对象的代码,是不是业务代码都要修改一遍?

此时引入我们的“工厂模式”!

2.1.引入“简单工厂模式”重构代码

2.1.1.定义用户接口并提供一个操作方法。

/*** 定义一个用户接口*/
public interface IUser {/*** 提供一个操作方法*/void doSometing();
}

2.1.2.Chef,Coder实现该接口并重写操作方法

/*** 厨师实体类*/
public class Chef implements IUser {/*** 提供一个做事情的方法*/@Overridepublic void doSometing(){System.out.println("厨师正在烹调食物...");}
}
/***  程序员实体类*/
public class Coder implements IUser {/*** 提供一个做事情的方法*/@Overridepublic void doSometing(){System.out.println("程序员正在编写程序...");}
}

2.1.3.定义工厂方法用于创建对象

/*** 定义工厂类*/
public class UserFactory {public static IUser createUser(String userType){IUser user = null;switch (userType){case "Chef" :user = new Chef();break;case "Coder" :user = new Coder();break;}return user;}
}

2.1.4.测试

/*** 测试类*/
public class Test {public static void main(String[] args) {IUser chef = UserFactory.createUser("Chef");IUser coder = UserFactory.createUser("Coder");chef.doSometing();coder.doSometing();}
}

可以看到业务调用方不依赖Chef和Coder了,并且没有了具体的对象创建过程,我们只是让工厂返回我们需要的对象,我们去使用就可以了至于对象的创建过程我们并不关心。回到上面的问题以后不管是创建对象前加日志,还是修改对象的名称,调用方的业务代码不需要更改只需要改工厂类相关的代码就可以了。

3.简单工厂模式总结

它把对象的创建过程封装起来,隐藏了对象创建的细节,根据外部传入的参数来决定返回哪一种对象,它的缺点就是如果要增加对象类型,或者修改某一个对象的创建方法时,就必须修改工厂类,这不符合对象编程设计原则之一的“开闭原则”。

开闭原则:对扩展开放,对修改封闭。在实现新的需求的时候,最好能够只是扩展而不去修改已经写好的代码,这样能够把新需求带来的风险降到最低。

二.抽象工厂模式

由上“简单工厂模式”可以看出,“厨师”,“程序员”对象都是在同一个工厂里面去生产。一旦生产“厨师”对象的工厂代码发生变化。就有可能影响到“程序员”对象的生产。因为都是使用的是同一个工厂,可能存在误改的情况。为了解决这个问题我们可以建两个工厂一个负责“厨师”另一个负责“程序员”对象的生产。这样就实现了解耦合。当修改生产“厨师”对象的工厂代码时不会影响到“程序员”工厂代码。因为两者是分开的。

上面的概念其实就是“抽象工厂模式”。抽象工厂把具体工厂需要做的事情定义好,所有具体的工厂都必须要实现抽象工厂里面的方法,这样业务调用方依赖的是抽象工厂而不是具体的工厂,实现了解耦合。

1.举个栗子

将“简单工厂”改造为“抽象工厂”。

/*** 工厂总接口,后续工厂实现此接口用于产生不同的对象*/
public interface IFactory {/*** 创建对象方法*/IUser createUser();
}
/*** 定义厨师工厂,用于产生“厨师”对象*/
public class ChefFactory implements IFactory{@Overridepublic IUser createUser() {Chef chef = new Chef();return chef;}
}
/*** 定义程序员工厂,用于产生“程序员”对象*/
public class CoderFactory implements IFactory{@Overridepublic IUser createUser() {Coder coder = new Coder();return coder;}
}
/*** 定义一个用户接口*/
public interface IUser {/*** 提供一个行为方法,后续新加的其它用户类型都实现此接口用于表达不同用户做不同事*/void doSometing();
}
/*** 厨师实体类*/
public class Chef implements IUser {/*** 实现IUser接口中做事情的方法*/@Overridepublic void doSometing(){System.out.println("厨师正在烹调食物...");}
}
/***  程序员实体类*/
public class Coder implements IUser {/*** 实现IUser接口中做事情的方法*/@Overridepublic void doSometing(){System.out.println("程序员正在编写程序...");}
}
/*** 测试类*/
public class Test {public static void main(String[] args) {// 创建工厂对象IFactory chefFactory = new ChefFactory();// 通过工厂创建“厨师”对象IUser chefUser = chefFactory.createUser();// 执行业务方法chefUser.doSometing();// 创建工厂对象CoderFactory coderFactory = new CoderFactory();// 通过工厂创建“程序员”对象IUser coderUser = coderFactory.createUser();// 执行业务方法coderUser.doSometing();}
}

2.抽象工厂模式总结

业务调用处需要具体的对象时就使用具体工厂类去创建对象,因为不同工厂是分开的当修改某个具体工厂时不会影响到其它工厂。抽象工厂模式的缺点也很明显,当新增一种对象的生产时需要额外增加一个具体的工厂类,如果新增的对象很多那么具体的工厂类就会非常多。其次它把具体的工厂对象创建过程暴露给了业务调用处,不利于解耦合。

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

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

相关文章

吃透2000-2024年600道真题和解析,科学高效通过2025年AMC8竞赛

为帮助孩子科学、有效备考AMC8竞赛,我整理了2000-2004年的全部AMC8真题(完整版共600道,且修正了官方发布的原试卷中的少量bug),并且独家制作成多种在线练习,利用碎片化时间,8个多月的时间足以通…

Django中的实时通信:WebSockets与异步视图的结合【第167篇—实时通信】

👽发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在现代Web应用程序中,实时通信已经成为了必不可少的功能之一。无论是在线聊天、…

爆肝3k字!掌握Spring与Redis的高效交互:从Jedis到Spring Data Redis

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

Spring Boot 多环境配置:YML 文件的三种高效方法

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

Linux内核之WRITE_ONCE用法实例(四十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

单链表实现通讯录-三万字

声明 这一篇文章我会从单链表的概念,单链表的原理,一直到通讯录项目单链表的实现,再把单链表的专用题型系统的讲解一下(文章较长)。同时建议学习单链表之前可以学习一下顺序表,作为知识铺垫顺序表&#xf…

【Java】@RequestMapping注解在类上使用

RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到控制器(controller类)的处理方法上。 Request Mapping 基础用法 在 Spring MVC 应用程序中,RequestDispatcher (在 Front Controller 之下) 这…

【HCIP学习】OSPF协议基础

一、OSPF基础 1、技术背景(RIP中存在的问题) RIP中存在最大跳数为15的限制,不能适应大规模组网 周期性发送全部路由信息,占用大量的带宽资源 路由收敛速度慢 以跳数作为度量值 存在路由环路可能性 每隔30秒更新 2、OSPF协议…

Spark-机器学习(2)特征工程之特征提取

在之前的文章中,我们了解我们的机器学习,了解我们spark机器学习中的MLIib算法库,知道它大概的模型,熟悉并认识它。想了解的朋友可以查看这篇文章。同时,希望我的文章能帮助到你,如果觉得我的文章写的不错&a…

【ARFoundation自学01】搭建AR框架,检测平面点击位置克隆物体

Unity开发ARFoundation相关应用首先安装ARFoundation包 然后设置XR 1.基础AR场景框架搭建 2.一个基本的点击克隆物体到识别的平面脚本 挂在XROrigin上 脚本AppController 脚本说明书 ## 业务逻辑 AppController 脚本旨在实现一个基本的 AR 应用程序功能:用户通过…

R语言使用installr包对R包进行整体迁移

今天分享一个R语言的实用小技巧,如果咱们重新安装了电脑(我重装了电脑)或者因为需要卸载旧版本的R软件,安装新版本的R,那么必然会造成R包的库缺失,需要重新下载,有些还不是官方的R包&#xff0c…

12.模板进阶(模板的全特化,偏特化,声明与定义分离)

1. 非类型模板参数 模板参数分类: 类型形参 与 非类型形参 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当…

爬取东方财富股票代码

我们打开东方财富网站&#xff1a;http://quote.eastmoney.com/stocklist.html 假如懒得爬&#xff0c;也可以用现成的股票数据源&#xff1a;https://stockapi.com.cn 这展示了所有股票信息&#xff0c;不过需要我们分页去爬取 我们可以查询具体的html代码&#xff1a; <…

服装连锁收银软件哪个好用

竞争激烈的服装连锁行业&#xff0c;选择一款高效可靠的收银软件至关重要。商淘云连锁收银软件作为业内领先的解决方案之一&#xff0c;备受关注和好评。本文将介绍商淘云连锁收银软件&#xff0c;并分享其在提升服装连锁店效率和客户体验方面的优势。 1. 商淘云连锁收银软件的…

异地组网如何安装?

【天联】是一款强大的异地组网安装工具&#xff0c;可以帮助企业实现远程设备的统一管理和协同办公。以下是【天联】可以应用的一些场景&#xff1a; 零售、收银软件应用统一管理&#xff1a;【天联】可以结合医药、餐饮、商超等零售业的收银软件&#xff0c;实现异地统一管理。…

OpenHarmony开发案例:【分布式遥控器】

1.概述 目前家庭电视机主要通过其自带的遥控器进行操控&#xff0c;实现的功能较为单一。例如&#xff0c;当我们要在TV端搜索节目时&#xff0c;电视机在遥控器的操控下往往只能完成一些字母或数字的输入&#xff0c;而无法输入其他复杂的内容。分布式遥控器将手机的输入能力…

解决QtCreator不能同时运行多个程序的方法

当我们运行QtCreator代码的时候&#xff0c;往往一个代码&#xff0c;可能需要打开好几个运行&#xff0c;但是会出现的情况就是&#xff0c;如果打开了一个界面&#xff0c;当我么再运行的时候&#xff0c;第一个界面就没有了&#xff0c;而且可能会出现终端报错的情况&#x…

Spectral Adversarial MixUp for Few-Shot Unsupervised Domain Adaptation论文速读

文章目录 Spectral Adversarial MixUp for Few-Shot Unsupervised Domain Adaptation摘要方法Domain-Distance-Modulated Spectral Sensitivity (DoDiSS&#xff09;模块Sensitivity-Guided Spectral Adversarial Mixup (SAMix)模块 实验结果 Spectral Adversarial MixUp for F…

上海计算机学会 2023年10月月赛 乙组T3 树的连通子图(树、树形dp)

第三题&#xff1a;T3树的连通子图 标签&#xff1a;树、树形 d p dp dp题意&#xff1a;给定一棵 n n n个结点的树&#xff0c; 1 1 1号点为这棵树的根。计算这棵树连通子图的个数&#xff0c;答案对 1 , 000 , 000 , 007 1,000,000,007 1,000,000,007取余数。题解&#xff1…

HTML内联框架

前言&#xff1a; 我们有时候打开网页时会有广告窗的出现&#xff0c;而这些窗口并不是来自于本站的&#xff0c;而是来自于外部网页&#xff0c;只是被引用到了自己网页中而已。这一种技术可以通过内联来实现。 标签介绍&#xff1a; HTML 内联框架元素 (<iframe>) 表示…