4-设计模式-工厂模式(设计模式学习笔记)

什么是设计模式?

设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。

使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。

在软件设计中,模式是一些经过了大量实际项目验证的优秀解决方案。熟悉这些模式的程序员,对某些模式的理解也许形成了条件反射。当合适的场景出现时,他们可以很快地找到某种模式作为解决方案。

工厂模式

工厂模式是用来创建对象的一种最常用的设计模式(创建型)。

我们不暴露创建对象的具体逻辑,而是将逻辑封装在一个函数中,那么这个函数就可以被视为一个工厂。

工厂模式根据抽象程度的不同可以分为:简单工厂工厂方法抽象工厂

简单工厂

简单工厂模式又被称为静态工厂方法模式。可以根据不同的参数返回

简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的类通常具有不同类的实例共同的父类。

1.工厂类角色:本模式的核心,含有一定的商业逻辑和判断逻辑,用来创建产品

2.抽象产品角色:一般是具体产品继承的父类或者实现的接口,例如运算类

3.具体产品角色:工厂类所创建的对象就是此角色的实例,例如乘法类,除法类,加法类,减法类

image.png

简单工厂模式优缺点:

优点:简单,只要有一个正确的参数,就可以获取需要的对象

缺点:如果后面需要增加产品,需要修改原代码逻辑。静态工厂方法不能被继承。

代码示例:

// remi老师的版本
    //抽象的产品类
    class Product{
        init(){
            console.log("你想怎么生产")
        }
    }

    //具体的产品
    class Hanbao extends Product{
        init(){
            console.log("生产汉堡")
        }
    }

    class Jitui extends Product{
        init(){
            console.log("生产鸡腿")
        }
    }

    //工厂
    class Factory{
        static getProduct(name){
            switch (name){
                case "Hanbao":
                    return new Hanbao()
                    break
                case  "Jitui":
                    return new Jitui()
                    break
                default:
                    throw new Error("没有你想要的")
                    break
            }
        }
    }

    Factory.getProduct("Hanbao").init() //工厂生产汉堡
    Factory.getProduct("Jitui").init() //工厂生产鸡腿
复制代码
// 我自己的版本
    //抽象的产品类
    class Calculation{
        toDo(x,y){
            console.log(`亲,你算什么东西?这可不是骂人啊`)
        }
    }

    //具体的产品
    class Add extends Calculation{
        toDo(x,y){
            console.log(`我要算加法:${x}+${y}=${x+y}`)
        }
    }

    class Minus extends Calculation{
        toDo(x,y){
            console.log(`我要算减法:${x}-${y}=${x-y}`)
        }
    }

    class Multiply extends Calculation{
        toDo(x,y){
            console.log(`我要算乘法:${x}*${y}=${x*y}`)
        }
    }

    class Divide extends Calculation{
        toDo(x, y) {
            console.log(`我要算除法:${x}/${y}=${x/y}`)
        }
    }

    //工厂
    class CalculationFactory{
        static getResult(name){
            switch (name){
                case "+":
                    return new Add()
                    break
                case "-":
                    return new Minus()
                    break
                case "*":
                    return new Multiply()
                    break
                case "/":
                    return new Divide()
                    break
                default:
                    throw new Error("请不要难为我游戏机")
                    break
            }
        }
    }

    CalculationFactory.getResult("+").toDo(6,6) // 12
    CalculationFactory.getResult("-").toDo(6,6) // 0
    CalculationFactory.getResult("*").toDo(6,6) // 36
    CalculationFactory.getResult("/").toDo(6,6) // 1
复制代码

工厂方法

工厂方法模式去掉了简单工厂模式中工厂方法的静态属性,使得它可以被子类继承。

这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。

1.抽象工厂角色:工厂方法模式的核心。具体工厂角色必须实现的接口或者必须继承的父类。

2.具体工厂角色:含有和具体业务逻辑有关的代码。创建对应的具体产品的对象。

3.抽象产品角色:是具体产品继承的父类或者实现的接口。

4.具体产品角色:具体工厂角色所创建的对象就是此角色的实例。

工厂方法是解决工厂不能被继承的问题,要符合开闭原则(对扩展开放,对修改封闭)。

image.png

工厂方法模式优缺点:

优点:符合开闭原则,增加一个产品,只需要添加一个具体的产品类和具体的工厂类,使用者无需关心产品如何去创造

缺点:系统代码比较复杂

代码示例:

// remi老师的版本
    //抽象的产品电脑 规则
    class Computer{
        //功能
        code(){
            console.log("某某电脑能写代码")
        }
    }

    //具体产品
    class Xiaomi extends  Computer{
        code() {
            console.log("小米电脑能写代码")
        }
    }

    class Dell extends Computer{
        code() {
            console.log("戴尔电脑能写代码")
        }
    }

    //抽象工厂
    class ComputerFactory{
        createComputer(){
            console.log("某某工厂生产某某电脑")
        }
    }

    //具体工厂
    class XiaomiFactory extends ComputerFactory{
        createComputer() {
            console.log("小米工厂生产小米电脑")
            return new Xiaomi()
        }
    }

    class DellFactory extends ComputerFactory{
        createComputer() {
            console.log("戴尔工厂生产戴尔电脑")
            return new Dell()
        }
    }

    let xiaomi = new XiaomiFactory() //实例对象小米
    xiaomi.createComputer().code() //实例对象调用方法

    let dell = new DellFactory() //实例对象戴尔
    dell.createComputer().code() //实例对象调用方法
复制代码
// 我自己的版本
    //抽象的产品计算 规则
    class Calculation{
        //功能
        toDo(){
            console.log("某某方法能进行数学计算")
        }
    }

    //具体产品
    class Add extends Calculation{
        toDo(x,y) {
            console.log(`能进行加法运算:${x}+${y}=${x+y}`)
        }
    }

    class Minus extends Calculation{
        toDo(x,y) {
            console.log(`能进行减法运算:${x}-${y}=${x-y}`)
        }
    }

    class Multiply extends Calculation{
        toDo(x,y) {
            console.log(`能进行乘法运算:${x}*${y}=${x*y}`)
        }
    }

    class Divide extends Calculation{
        toDo(x,y) {
            console.log(`能进行除法运算:${x}/${y}=${x/y}`)
        }
    }

    //抽象工厂
    class CalculationFactory{
        createCalculation(){
            console.log("某某工厂生产某某运算")
        }
    }

    //具体工厂
    class AddFactory extends CalculationFactory{
        createCalculation() {
            console.log("加法工厂生产加法运算")
            return new Add()
        }
    }

    class MinusFactory extends CalculationFactory{
        createCalculation() {
            console.log("减法工厂生产减法运算")
            return new Minus()
        }
    }

    class MultiplyFactory extends CalculationFactory{
        createCalculation() {
            console.log("乘法工厂生产乘法运算")
            return new Multiply()
        }
    }

    class DivideFactory extends CalculationFactory{
        createCalculation() {
            console.log("除法工厂生产除法运算")
            return new Divide()
        }
    }

    let myAdd = new AddFactory() // 实例化对象
    myAdd.createCalculation().toDo(6,6) // 实例化对象调用方法

    let myMinus = new MinusFactory()
    myMinus.createCalculation().toDo(6,6)

    let myMultiply = new MultiplyFactory()
    myMultiply.createCalculation().toDo(6,6)

    let myDivide = new DivideFactory()
    myDivide.createCalculation().toDo(6,6)
复制代码

抽象工厂

抽象工厂模式工厂方法模式的泛化版本,工厂方法模式是一种特殊的工厂模式。在工厂方法模式中,一个具体工厂只能生产一种产品,而抽象工厂模式中,一个具体工厂可以生产多个产品。

1.抽象工厂角色:工厂方法模式的核心。是具体工厂角色必须实现的接口或者必须继承的父类。

2.具体工厂角色:含有和具体业务逻辑有关的代码。创建对应的具体产品的对象。

3.抽象产品角色:是具体产品继承的父类或者是实现的接口。

4.具体产品角色:具体工厂角色所创建的对象就是此类角色的实例。

代码示例:

// remi老师的版本
    //抽象产品 电脑
    class Computer{
        //功能
        code(){
            //
        }
    }

    //具体产品 电脑
    class Xiaomi_c extends Computer{
        code(){
            console.log("xiaomidiannao")
        }
    }

    class Dell_c extends Computer{
        code(){
            console.log("delldiannao")
        }
    }

    //抽象产品 手机
    class Phone{
        //功能
        call(){
            //
        }
    }

    //具体产品 手机
    class Xiaomi_p extends Phone{
        call(){
            console.log("xiaomishouji")
        }
    }

    class Dell_p extends Phone{
        call(){
            console.log("dellshouji")
        }
    }

    //抽象工厂
    class CPFactory{
        //生产电脑的规则
        createComputer(){
            //
        }

        //生产手机的规则
        createPhone(){
            //
        }
    }

    //具体工厂
    class XiaomiFactory extends CPFactory{
        createComputer() {
            console.log("xiaomidiannao")
            return new Xiaomi_c()
        }
        createPhone() {
            console.log("xiaomishouji")
            return new Xiaomi_p()
        }
    }

    class DellFactory extends CPFactory{
        createComputer() {
            console.log("delldiannao")
            return new Dell_c()
        }
        createPhone() {
            console.log("dellshouji")
            return new Dell_p()
        }
    }

    //需要的时候直接实例具体工厂
    let xiaomi = new XiaomiFactory()
    xiaomi.createComputer().code() //小米工厂调用create电脑方法再调用code方法
    xiaomi.createPhone().call() //小米工厂调用create手机方法再调用call方法
复制代码
// 我自己的版本
    //抽象产品 游戏
    class Game{
        //功能
        keJin(){console.log("游戏可以氪金")}
    }

    //具体产品 游戏
    class tencentGame extends Game{
        keJin(){
            console.log("腾讯游戏:氪金前你是我儿子,氪金后你就是我爸爸!")
        }
    }

    class neteaseGame extends Game{
        keJin(){
            console.log("网易游戏:氪金前你是我孙子,氪金后你勉强算我儿子。")
        }
    }

    //抽象产品 音乐
    class Music{
        listen(){
            console.log("音乐可以听")
        }
    }

    //具体产品 音乐
    class qqMusic extends Music{
        listen() {
            console.log("QQ音乐:听歌吗?绿钻了解一下")
        }
    }

    class wangyiyunMusic extends Music{
        listen() {
            console.log("网易云:到点了到点了。生不出人,我很抱歉。")
        }
    }

    //抽象工厂
    class Factory{
        createGame(){
            console.log("某某工厂生产某某游戏")
        }

        createMusic(){
            console.log("某某工厂生产某某音乐")
        }
    }

    //具体工厂
    class tencentFactory extends Factory{ //鹅厂
        createGame() {
            console.log("腾讯:该充钱了,爸爸")
            return new tencentGame()
        }

        createMusic() {
            console.log("QQ音乐:QQ豪华绿钻了解一下")
            return new qqMusic()
        }
    }

    class neteaseFactory extends Factory{ //猪厂
        createGame() {
            console.log("网易:还不氪金,孙子")
            return new neteaseGame()
        }

        createMusic() {
            console.log("网易云:生吃个人,我很抱歉")
            return new wangyiyunMusic()
        }
    }

    //鹅厂
    let tencent = new tencentFactory() // 实例化具体工厂对象,鹅厂
    tencent.createGame().keJin() // 鹅厂调用内部方法,实例化具体产品对象--游戏,游戏调用内部方法
    tencent.createMusic().listen() // 鹅厂调用内部方法,实例化具体产品对象--QQ音乐,QQ音乐调用内部方法

    //猪厂
    let wangyi = new neteaseFactory() // 实例化具体工厂对象,猪厂
    wangyi.createGame().keJin() // 猪厂调用内部方法,实例化具体产品对象--游戏,游戏调用内部方法
    wangyi.createMusic().listen() // 鹅厂调用内部方法,实例化具体产品对象--网易云,网易云调用内部方法
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享