【Kotlin设计模式】Kotlin实现工厂模式

前言


工厂模式(Factory Pattern)是一种创建型设计模式,提供一个创建对象的接口,不暴露对象的创建过程。它将实例化对象的任务交给子类或具体实现,从而使得客户端代码与具体类解耦。

工厂模式主要分为以下三类:

1、简单工厂模式(Simple Factory
2、工厂方法模式(Factory Method
3、抽象工厂模式(Abstract Factory


实现

1、简单工厂模式

Kotlin中可以借助伴生对象companion object来实现工厂模式,客户端不需要知道具体产品类的类名,只需要创建将产品类型传给工厂即可,降低了客户端与具体产品类的耦合,适合产品类目较少且不变动的情况下。

当后续要不断增加产品类型,这种模式就不太适合了,新增产品需要修改工厂类,则会导致工厂类太过臃肿,不利于维护。

在这里插入图片描述

假设有个小产品生产工厂,生产不同类目的产品,新建产品接口、这个工厂只能生产的产品类目有篮球、牛奶、笔。


interface Product {fun doWhat()
}//踢足球
class FootBall : Product {override fun doWhat() {println("Football can be played")}
}//喝牛奶
class Milk : Product {override fun doWhat() {println("Milk can be drunk")}
}//写字
class Pen :Product{override fun doWhat() {println("Pen can be write")}
}

生产产品的过程如下,商务有牛奶的订单交由产线生产,客户端告诉产线生产牛奶即可。


class SimpleFactory {companion object {fun createProduct(type: String): Product {return when (type) {"FootBall" -> { FootBall() }"Milk" -> { Milk() }"Pen" -> { Pen() }else -> {throw IllegalArgumentException("unKnow product type")}}}}
}SimpleFactory.createProduct("Milk").doWhat()  //输出  Milk can be drunkSimpleFactory.createProduct("Cup").doWhat()   //输出  UnKnow product type

2、工厂方法模式

在更复杂的场景中,可以使用接口或抽象类来定义工厂方法,这样可以允许不同的工厂类创建不同类型的对象。

在这里插入图片描述


interface Factory{fun createProduct():Product
}/*** 球生成工厂*/
class BallFactory : Factory {override fun createProduct(): Product {return FootBall()}
}/*** 牛奶生产工厂*/
class MilkFactory : Factory {override fun createProduct(): Product {return Milk()}
}/*** 笔生产工厂*/
class PenFactory : Factory {override fun createProduct(): Product {return Pen()}
}

创建产品的过程不放到不同的工厂中,每个工厂只生成对应的产品即可,实例化过程放到对应的子类中进行,但是这样的坏处就是增加类的数目,增加了系统的复杂性。


3、抽象工厂模式


抽象工厂模式提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类,但是这样也会增加系统的复杂性和类的数量。

假设牛奶厂家做活动,买一箱牛奶送一辆豪车,蒙牛和保时捷联合、伊利和宾利合作,牛奶和车要在同一工厂生产,这种情况可以使用抽象工厂模式来实现。

在这里插入图片描述

抽象工厂模式的核心是抽象工厂接口和具体工厂类,通常包括:

1、抽象产品、接口(AbstractProduct


interface Milk {fun taste()
}interface Car {fun slogan()
}

2、具体产品(ConcreteProduct


class MengNiu : Milk {override fun taste() {println("【蒙牛】纯甑酸奶砀山黄桃燕麦味")}
}class YiLi : Milk {override fun taste() {println("【伊利】安慕希丹东草莓酸奶")}
}class Porsche : Car {override fun slogan() {println("only Porsche can beat Porsche")}
}class Bentley : Car {override fun slogan() {println("Bentley,Be Extraordinary")}
}

3、抽象工厂(AbstractFactory

/*** 抽象工厂类,定义生产牛奶和车接口*/
interface AbstractFactory {fun createMilk(): Milkfun createCar(): Car
}

4、具体工厂(ConcreteFactory


//MengNiu同步生产活动蒙牛牛奶和保时捷
class FactoryMengNiuUnion : AbstractFactory {override fun createMilk(): Milk {return MengNiu()}override fun createCar(): Car {return Porsche()}
}//YiLi同步生产活动伊利牛奶和宾利
class FactoryYiLiUnion: AbstractFactory {override fun createMilk(): Milk {return YiLi()}override fun createCar(): Car {return Bentley()}
}

5、客户端(Client

val factoryA:AbstractFactory = FactoryMengNiuUnion()val mengNiuMilk = factoryA.createMilk() mengNiuMilk.taste()	 				//【蒙牛】纯甑酸奶砀山黄桃燕麦味val porsche = factoryA.createCar() porsche.slogan()						// only Porsche can beat Porscheval factoryB:AbstractFactory = FactoryYiLiUnion()val yiLiMilk = factoryB.createMilk()yiLiMilk.taste()  				   //【伊利】安慕希丹东草莓酸奶val bentley = factoryB.createCar()bentley.slogan()     				   //Bentley,Be Extraordinary

总结

工厂模式在解耦对象创建和使用、提高系统扩展性和维护性方面具有明显优势,但在系统复杂性和管理难度上也存在一定的代价。选择是否使用工厂模式应基于系统需求的复杂程度和对象创建的复杂性。

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

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

相关文章

图像处理之:Video Processing Subsystem(一)

免责声明: 本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下,作者不对因使用本文内容而导致的任何直接或间接损失承担责任,包括但不限于数据丢失、业务中断或其他经济…

ucharts图表滚动

背景&#xff1a; 使用ucharts绘制折线图&#xff0c;当数据项多的时候&#xff0c;横坐标显示的文字会重合&#xff0c;故想到滑动 项目代码使用的是原生的代码&#xff0c;而非ucharts的组件&#xff1a; <template><view><canvas canvas-id"chartsLi…

各类软件历史版本的下载地址

postman,notpad等 https://www.filehorse.com/software-developer-tools/https://www.filehorse.com/software-developer-tools/

FreeRTOS学习:内存管理

FreeRTOS内存管理简介 在使用 FreeRTOS 创建任务、队列、信号量等对象的时候&#xff0c; FreeRTOS 一般都提供了两种方法&#xff0c; 动态方法创建&#xff1a;自动地从 FreeRTOS 管理的内存堆中申请所创建对象所需的内存&#xff0c;在对象被删除后&#xff0c;又可以将这…

day33(mysql57主从从+mycat读写分离+java项目结合mycat数据库+lvs_dr轮询调用java项目)

1.设置主从从mysql57服务器 &#xff08;1&#xff09;配置主数据库 [rootmsater_5 ~]# systemctl stop [rootmsater_5 ~]# setenforce 0 [rootmsater_5 ~]# systemctl disable Removed symlink /etc/systemd/system/multi-user.target.wants/# ls anaconda-ks.cfg mysql-5.7…

Qt实现圆型控件的三种方法之设置样式表

前言 最近在研究绘制各种形状的控件&#xff0c;这里专门挑出圆形的控件进行记录&#xff0c;其它形状的也大差不差&#xff0c;会了圆形的之后其它的也类似。 正文 这里我挑出Label来进行举例。 通过设置样式表 (QSS) 这种方法简单且适用于不需要自定义绘制的场景。就是要…

vue2项目 预渲染 Unable to prerender all routes 错误排查与解决方案

前言 今天在做我的Vue2项目的SEO优化时&#xff0c;我采用了prerender-spa-plugin与vue-meta-info的一套官网前端SEO预渲染方案。 但是&#xff0c;在打包时&#xff0c;报错Unable to prerender all routes。尝试了很多种网上方案&#xff0c;都没有成功&#xff0c;最后从源…

基于vue3和audio封装的简易音频播放器

样式如图所示 <template><div class"audio-player"><div class"player_top" flex-ac flex-justify-between ><div class"fileName genericTitle" fs-28 l-height-32 height-64 pr-42 flex-ac><span class"t…

维护和升级LabVIEW程序

在维护和升级LabVIEW程序时&#xff0c;需要全面考虑代码的现状和未来的需求。以下是各个方面的详细注意事项&#xff0c;以确保程序能够在稳定性和性能方面得到提升。 1. 理解现有代码: 深入代码分析: 仔细阅读现有的代码&#xff0c;了解其逻辑结构、数据流、和控制流程。关注…

中国大模型平台市场份额最新排名Top5!场景化应用昭示新蓝海

8月21日&#xff0c;IDC&#xff08;国际数据公司&#xff09;首次发布了《中国大模型平台市场份额&#xff0c;2023&#xff1a;大模型元年 —— 初局》。数据显示&#xff0c;2023年中国大模型平台及相关应用市场规模达17.65亿元人民币。 在过去的2023年&#xff0c;行业对于…

会话跟踪方案:Cookie Session Token

什么是会话技术&#xff1f; Cookie 以登录为例&#xff0c;用户在浏览器中将账号密码输入并勾选自动登录&#xff0c;浏览器发送请求&#xff0c;请求头中设置Cookie&#xff1a;userName:张三 ,password:1234aa &#xff0c;若登录成功&#xff0c;服务器将这个cookie保存…

「数组」数组双指针算法合集:二路合并|逆向合并|快慢去重|对撞指针 / LeetCode 88|26|11(C++)

目录 概述 1.二路合并 思路 复杂度 Code 2.逆向合并 思路 复杂度 Code 3.快慢去重 思路 复杂度 Code 4.对撞指针 思路 复杂度 Code 总结 概述 数组的线性枚举是我们学习编程时遇到的第一种枚举手段。但是它看起来有点愚蠢&#xff1a;只有一个索引i承担全部…

学生党蓝牙耳机哪个牌子性价比高?推荐四款内行精选百元耳机!

作为没有什么经济来源的学生党&#xff0c;唯一来钱的途径就是家里给的生活费。所以在选择一款蓝牙耳机时就很纠结&#xff0c;那么首先你得清楚学生党的购物习性&#xff0c;因为大部分学生党在买东西时因为经济能力问题&#xff0c;主要追求的还是性价比&#xff0c;可以在实…

IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀放大器

IP-DAR-250、IP-DAR-43C-L、IP-DAR-43C-H、IP-RDS-222、IP-PRZ-59-AM12、EG-TRZ-42-L、EG-TRZ-42-H比例减压阀 EE-PRB、EE-PRD比例压力阀 EE-P2G、ET-P2S、EB-P2A、EE-P2A、ET-P2A、EE-P2H、EG-F2A、EU-F2A比例流量阀 EF-F3G、EU-F3G比例压力补偿流量阀 EQ-S4M、EG-S4M、EQ…

DVWA靶场通关(CSRF)

CSRF 是跨站请求伪造&#xff0c;是指利用受害者尚未失效的身份认证信息&#xff08;cookie、会话等&#xff09;&#xff0c;诱骗其点击恶意链接或者访问包含攻击代码的页面&#xff0c;在受害人不知情的情况下以受害者的身份向&#xff08;身份认证信息所对应的&#xff09;服…

eNSP 华为ACL配置

华为ACL配置 需求&#xff1a; 公司保证财务部数据安全&#xff0c;禁止研发部门和互联网访问财务服务器&#xff0c;但总裁办不受影响 R1&#xff1a; <Huawei>sys [Huawei]sys Router1 [Router1]undo info-center enable [Router1]int g1/0/0 [Router1-GigabitEth…

开放式耳机为什么性价比高?四款开放式蓝牙耳机排行榜前十名推荐

如果说需要高性价比的蓝牙耳机推荐的话&#xff0c;我会比较推荐开放式耳机&#xff0c;因为这类的耳机产品价格普遍都不会太高&#xff0c;但配置却都很好。那除了性价比高&#xff0c;开放式耳机还有其他好的地方吗&#xff1f;那当然是有的&#xff0c;对于蓝牙耳机来说&…

HTML+JS谁是卧底游戏

先说一句&#xff1a;一段时间没发文章&#xff0c;好多僵尸粉关注我&#xff0c;这CSDN&#x1f620; 主要功能 玩家设置&#xff1a;在游戏开始前&#xff0c;输入总人数、卧底人数和白板人数。系统会自动计算出剩下的平民人数&#xff0c;并随机分配身份。 身份查看&#…

DHCP协议-CSP认证

文章目录 DHCP协议 DHCP协议 stringstream的用法 应用实践 #include<bits/stdc.h>using namespace std;signed main() {string s"wo shi wwl, also wlw";stringstream ss;ss<<s;while(ss>>s){if(s[s.size()-1],) s[s.size()-1] ;cout<<s<…

授权cleanmymac访问全部磁盘 Mac授权访问权限 cleanmymac缺少权限

CleanMyMac是Mac系统下的一款专业的苹果电脑清理软件&#xff0c;同时也是一款优秀的电脑系统管理软件。它能有效清理系统垃圾&#xff0c;快速释放磁盘内存&#xff0c;缓解卡顿现象&#xff0c;保障系统顺畅地运行。 全磁盘访问权限&#xff0c;就好比机场内进行的安全检查。…