当前位置: 首页 > news >正文

【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

总结

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【WPF】WPF学习之面试常问问题
  • Visual Studio中 自动生成版本号递增版本号
  • React 入门第四天:理解React中的路由与导航
  • 【C#】字段
  • 点晴oa办公系统提效管理+业务协同
  • 极光公布2024年第二季度财报
  • MYSQL -NATURAL JOIN ,单行函数
  • FFmpeg的入门实践系列四(AVS)
  • 给鼠标一个好看的指针特效 鼠标光标如何修改形状?
  • Cisco-综合实验二
  • Linux--NAT,代理服务,内网穿透
  • Python网络爬虫模拟登录与验证解析
  • 为什么要学习 CCRC-PIPP
  • 若依后端 MyBatis改为MyBatis-Plus
  • SIMCom芯讯通A7680C发起HTTP通讯:在UI串口进行模拟;代码调用API操作
  • 分享的文章《人生如棋》
  • 【mysql】环境安装、服务启动、密码设置
  • 【前端学习】-粗谈选择器
  • CSS3 变换
  • ES学习笔记(12)--Symbol
  • Git 使用集
  • IndexedDB
  • java8-模拟hadoop
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Median of Two Sorted Arrays
  • node-glob通配符
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 多线程事务回滚
  • 服务器之间,相同帐号,实现免密钥登录
  • 判断客户端类型,Android,iOS,PC
  • 驱动程序原理
  • 使用权重正则化较少模型过拟合
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • Hibernate主键生成策略及选择
  • ​一文看懂数据清洗:缺失值、异常值和重复值的处理
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • ## 1.3.Git命令
  • ## 基础知识
  • #传输# #传输数据判断#
  • #数据结构 笔记三
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (排序详解之 堆排序)
  • (一)u-boot-nand.bin的下载
  • (转)socket Aio demo
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .“空心村”成因分析及解决对策122344
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .NET Remoting学习笔记(三)信道
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NET程序员迈向卓越的必由之路