一周两个设计模式—设计模式之工厂模式(第一周)

举报
浮生闲半日 发表于 2021/11/09 14:14:20 2021/11/09
【摘要】 设计模式在软件开发中占据了很重要的地位,无论阅读源码还是一些优秀的开源类库都涉及到设计模式的内容,所以就有了这次的文章,一周两个设计模式,争取在三个月内把设计模式从头到尾都学习一遍,希望大家能给更多的意见。今天是第一个设计模式,工厂模式,工厂模式分为简单工厂模式和抽象工厂模式,抽象工厂模式是对简单工程模式的一种扩展,下面会慢慢介绍的,现在先来看看简单工厂模式。 简单工厂模式适用范围:当一个类...

设计模式在软件开发中占据了很重要的地位,无论阅读源码还是一些优秀的开源类库都涉及到设计模式的内容,所以就有了这次的文章,一周两个设计模式,争取在三个月内把设计模式从头到尾都学习一遍,希望大家能给更多的意见。

今天是第一个设计模式,工厂模式,工厂模式分为简单工厂模式和抽象工厂模式,抽象工厂模式是对简单工程模式的一种扩展,下面会慢慢介绍的,现在先来看看简单工厂模式。

简单工厂模式

适用范围:
当一个类不知道它所必须创建的对象的类的时候,知道要干什么但是实现的方法有很多,
具体实现的时候能够确定选择实现的方式。

工厂模式简单点来说就是我知道要做什么,但是不同的条件实现的方式不同,但是整个过程是一样的,例如使用硬件设备来读取身份证,虽然硬件设备是不同的,但是整体流程无差异,都是打开设备,读取卡片,停止读取卡片,关闭设备这四个步骤,所以这个时候就可以使用工厂模式了。

/**
*抽象身份证读取的方法
**/
interface IdCard {

   fun openDevice()  //打开设备

   fun startRead() //开始读卡

   fun stopRead() //停止读卡

   fun closeDevice() //关闭设备

}

抽象完方法,下面就该实例化了,分别实例化两个不同的厂商的身份证模块

/**

  • A读卡器的读卡设备
    */
class IdCardA:IdCard {

    val showTag = "IdCardA"

    override fun openDevice() {
       Log.v(showTag,"打开设备了")
    }

    override fun startRead() {
        Log.v(showTag,"开始读卡了")
    }

    override fun stopRead() {
        Log.v(showTag,"停止读卡了")
    }

    override fun closeDevice() {
        Log.v(showTag,"关闭设备了")
    }
}

实例化设备B

/**
 * B读卡器的读卡设备
 */
class IdCardB:IdCard {
    val showTag = "IdCardB"

    override fun openDevice() {
        Log.v(showTag,"打开设备了")
    }

    override fun startRead() {
        Log.v(showTag,"开始读卡了")
    }

    override fun stopRead() {
        Log.v(showTag,"停止读卡了")
    }

    override fun closeDevice() {
        Log.v(showTag,"关闭设备了")
    }
}

这样就实现了具体读取身份证的功能了,下面就该创建工厂了

object Factory {

    fun getIdCard(type:Int):IdCard{

        return if(type==1) IdCardA() else IdCardB()

    }
}

到这里一个简单的工厂模式就完成了,通过代码我们可以知道工厂模式的优点

1、扩展比较好,如果添加一个新的种类的身份证读卡器只需要实现IdCard接口就可以了,修改比较方便

2、客户端无需知道所创建具体产品的类名,只需知道参数即可。

3、也可以引入配置文件,在不修改参数的情况下更换和添加新的具体产品类。

这样肯定会有朋友询问,这是一个种类的产品,我要是有多个种类的产品和多个种类的实现方式该怎么样呢,
例如 创建两个农场,一个养马种菜,一个养牛种花,这肯定使用上面的方式就不能实现了,那该怎么处理呢?这就引入了抽象工厂模式了

抽象工厂模式

适用范围:一个系统要独立于它的产品的创建、组合和表示时,不同的种类有不同的具体实现

结合代码介绍这种方式的实现,创建两个农场,一个养马种菜,一个养牛种花,

首先我们需要抽象一个Animal,包括动物的所有方法

interface Animal {
    fun showAnimal()
}

实例化出产品 牛和马的实体类

//马
class Horse:Animal {
    override fun showAnimal() {
        Log.v("Animal","i am a horse")
    }
}
//牛
class Cattle:Animal {
    override fun showAnimal() {
        Log.v("Animal","I am a cattle")
    }
}

抽象植物

interface Plant {
    fun show()
}

实例化菜和花朵

class Flower:Plant {
    override fun show() {
        Log.v("Plant","i am a flower")
    }
}
class Vegetables:Plant {
    override fun show() {
        Log.v("Plant","i am a vegetables")
    }
}

准备的已经都有了,牛、马、花朵和蔬菜已经都new出来了,下面应该抽象工厂了

//抽象农场,里面可以饲养动物和种植植物了
interface AbstractFarm {

    fun newAnimal():Animal

    fun newPlant():Plant
}

实例化农场

class FarmA:AbstractFarm {
    override fun newAnimal(): Animal {
        return Horse()
    }

    override fun newPlant(): Plant {
        return Flower()
    }
}
class FarmB:AbstractFarm {
    override fun newAnimal(): Animal {
        return Cattle()
    }

    override fun newPlant(): Plant {
        return Vegetables()
    }
}

大功告成

 class AbstractFactoryActivity:AppCompatActivity() {
    lateinit var farm:AbstractFarm
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_abstract_factory)

        findViewById<Button>(R.id.btnFarmA).setOnClickListener {
            farm = FarmA()
        }

        findViewById<Button>(R.id.btnFarmB).setOnClickListener {
            farm = FarmB()
        }

        findViewById<Button>(R.id.btnAnimal).setOnClickListener {
            farm.newAnimal().showAnimal()
        }

        findViewById<Button>(R.id.btnPlant).setOnClickListener {
            farm.newPlant().show()
        }
    }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。