Android 工厂设计模式的使用:咖啡机,可以做拿铁,可以做美式等等。

大家好呀~,我是前期后期,在网上冲浪的一名程序员,分享一些自己学到的知识,希望能够帮助大家节省时间。

目录


一、为什么使用:问题是什么

我们有一款纸币器,但是纸币器有三种通讯方式:ICT RS32、MDB以及脉冲。那么你是要什么样的呢?

可能平常我们就创建一个IF语句做判断,然后返回对应的对象。

kotlin 复制代码
if(ict rs232){
  // 创建对象
}else if(MDB){
  // 创建对象
}else if(脉冲){
  // 创建对象
}

如果后面还有新增的通讯方式,那么我们得修改这个IF语句。比如后面我要用到退钞,或者收钞,又得加判断来觉得使用那个对象去发送,非常的麻烦。

总结一下缺点:

  1. 可维护性差:如果时间久了,你可能就忘记了,如果说有客户有一些定制的设置在里面,越来越多,那么就会非常的复杂,代码过于混乱,也不利于排查问题,如果修改一处,可能会影响到其他定制设置。
  2. 不利于扩展:新增一个if,很多地方要修改,比如创建对象的时候,收钞的时候等等。

接下来,我们介绍一种设计模式:工厂设计模式,来优化我们的代码。


二、工厂设计模式是什么?

工厂设计模式是一种创建型设计模式,旨在通过定义一个创建对象的接口来分离对象的创建与使用代码。它使得类的实例化被推迟到子类,或者通过某种方式来参数化,从而允许在运行时动态地选择具体的实现类。

也就是,要定义一个接口、子类和工厂类,接口我们可以理解为是纸币通讯方式,子类就是具体的实现,如:ICT RS232,MDB和脉冲,而工厂类就是用于返回什么子类


三、具体的接口和子类

3.1 接口类

kt 复制代码
interface PaySendData {
    //初始化纸币器
    fun billInit()

    //托管
    fun billEnable(enableMoney:String, enableColl:String){}

    //压钞
    fun squeezeMoney()

    //初始化信用卡器
    fun initCreditCard(){}

}

3.2 ICT RS232子类

kt 复制代码
object PaySendDataICT : PaySendData {
    

    override fun billInit() {
    }

    override fun squeezeMoney() {
    }
}

可以看到,为什么我接口里面会有一些默认的实现呢?因为有一些方法,并不是所有子类都需要实现的。有些子类没有这个功能。

3.3 MDB子类

kt 复制代码
object PaySendDataMDBStrategy : PaySendDataStrategy {

    override fun billInit() {
    }

    override fun billEnable(enableMoney: String, enableColl: String) {
    }

    override fun initCreditCard() {
    }
    
    override fun squeezeMoney() {
    }

}

3.4 工厂类

kt 复制代码
// 工厂类
class PaySendDataFactory {

    fun createStrategy(type: StrategyType): PaySendDataStrategy {
        return when (type) {
            StrategyType.MDB -> PaySendDataMDBStrategy
            StrategyType.ICT -> PaySendDataICTStrategy
        }
    }
}

enum class StrategyType {
    MDB, ICT
}

3.5 使用工厂类进行创建

kt 复制代码
val createStrategy = PaySendDataFactory().createStrategy(StrategyType.MDB)
createStrategy.billInit()

好了到这里,我们的就大功告成了。

比如如果我新增脉冲协议,那么我只需要修改工厂类就可以。

kt 复制代码
// 工厂类
class PaySendDataFactory {

    fun createStrategy(type: StrategyType): PaySendDataStrategy {
        return when (type) {
            StrategyType.MDB -> PaySendDataMDBStrategy
            StrategyType.ICT -> PaySendDataICTStrategy
            StrategyType.PULSE -> PaySendDataPulseStrategy
        }
    }
}

enum class StrategyType {
    MDB, ICT,PULSE
}

如果说我要换成其他协议,那么,创建对象的时候,只需要修改这个枚举就可以。

kt 复制代码
val createStrategy = PaySendDataFactory().createStrategy(StrategyType.ICT)
createStrategy.billInit()

其他地方不用改动,因为我们用的billInit方法是一样的,只是每个协议的底层实现不一样。


四、工厂设计模式总结

上述,我们使用的是一种简单工厂设计模式。 如果将来需要支持更多种类的纸币器或者需要对纸币器进行更复杂的配置,可以考虑使用工厂方法模式或抽象工厂模式。不过,对于当前的需求来说,简单工厂模式已经提供了足够的灵活性和可扩展性。

应用场景:

  1. 产品具有明显的继承关系,且产品的类型不宜太多。
  2. 所以的产品具有相同的方法和类似的属性,使用者不关心具体的类型,只希望传入合适的参数能返回合适的对象。

优点:

● 实现简单、结构浅析

缺点:

● 如果产品的种类非常多,createProduct 方法会变得非常庞大,switch ... case ...(或 if ... else ...)的判断会变得非常多。

● 不符合开放---封闭原则(对拓展开放,对修改封闭),如果要增加或删除一个产品种类,就要修改 switch ... case ...(或 if ... else ...)的判断代码。

尽管简单工厂模式不符合开放---封闭原则,但因为它简单,你仍然能在很多项目中看到它。

好了,这篇文章就介绍到这里,我是前期后期,我们 下一篇文章 见·~

相关推荐
oscar99918 分钟前
Maven项目中不修改 pom.xml 状况下直接运行OpenRewrite的配方
java·maven·openrewrite
南宫生18 分钟前
力扣-数据结构-3【算法学习day.74】
java·数据结构·学习·算法·leetcode
工业甲酰苯胺24 分钟前
聊一聊 C#线程池 的线程动态注入
java·开发语言·c#
m0_7482402531 分钟前
docker--压缩镜像和加载镜像
java·docker·eureka
向宇it35 分钟前
【从零开始入门unity游戏开发之——C#篇30】C#常用泛型数据结构类——list<T>列表、`List<T>` 和数组 (`T[]`) 的选择
java·开发语言·数据结构·unity·c#·游戏引擎·list
葡萄架子36 分钟前
Python中的logger作用(from loguru import logger)
java·前端·python
daopuyun1 小时前
GB/T34944-2017 《Java语言源代码漏洞测试规范》解读——安全功能
java·开发语言·安全
编程洪同学1 小时前
Spring Boot 中实现自定义注解记录接口日志功能
android·java·spring boot·后端
bandaoyu1 小时前
【设计模式】装饰器模式(Decorator Pattern)
设计模式·装饰器模式
小小药1 小时前
009-spring-bean的实例化流程
java·数据库·spring