JavaScript-设计模式(二) 工厂模式

JavaScript-设计模式(二) 工厂模式

工厂模式定义:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

分类:简单工厂模式 、工厂方法模式

目的:工厂模式的目的是为了实现解耦,将对象的创建和使用分开,即应用程序将对象的创建和初始化职责交给工厂对象。

作用:

1.降低代码重复。由于创建过程都由工厂统一的管理,有利于当业务发生变化之后的修改

2.工厂模式将创建和使用分离,使用者不需要知道具体的创建过程,只需要使用即可。

3.类本身有很多子类,并且经常性发生变化。

4.提高代码的可维护性

使用场景:

//1、您需要一辆汽车,可以直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。 
//2、Hibernate 换数据库只需换方言和驱动就可以。

实现一个简单工厂模式:

function Person(n,a) {

          this.name = n
          this.age = a
      }
      let a = new Person("麻子",18)
      console.log(a);

工厂方法模式: (使创建过程延迟早子类进行)

//烧烤  
class Grill{
    constructor(){
        this.price = 20
        this.time = 15
    }
    done(){
        console.log(`Grill搞定了,价格${this.price},耗时${this.time}分钟`);
    }
} 

//面条
class Noodles{
   constructor(){
        this.price = 20
        this.time = 15
    }
    done(){
        console.log(` Noodles搞定了,价格${this.price},耗时${this.time}分钟`);
    }
}

//牛排
class Steak{
   constructor(){
        this.price = 50
        this.time = 20
    }
    done(){
        console.log(`Steak搞定了,价格${this.price},耗时${this.time}分钟`);
    }
}


//开放一个对外的窗口
function shop(name){
   let goods = null
   switch(name){
       case "Steak":
           goods = new Steak()
           break
       case "Noodles":
           goods = new Noodles()
           break
       case "Grill":
           goods = new Grill()
           break 
   }
   return goods
}
let a = shop("Steak");
let b = shop("Noodles");
let c = shop("Grill");
a.done()
b.done()
c.done()

此时代码还是比较分散 需要我们进一步改进 便于维护,如下:

//开放一个对外的窗口
function shop(name) {
    // 原材料
    let goods = null
    //烧烤  
    class Grill {
        constructor() {
            this.price = 20
            this.time = 15
        }
        done() {
            console.log(`Grill制作完成,价格${this.price},耗时${this.time}分钟`);
        }
    }

    //面条
    class Noodles {
        constructor() {
            this.price = 20
            this.time = 15
        }
        done() {
            console.log(`Noodles制作完成,价格${this.price},耗时${this.time}分钟`);
        }
    }

    //牛排
    class Steak {
        constructor() {
            this.price = 50
            this.time = 20
        }
        done() {
            console.log(`Steak制作完成,价格${this.price},耗时${this.time}分钟`);
        } 
    }
    
    //米饭
    class Rice{
        constructor(){
            this.price = 10
            this.time = 10
        }
        done() {
            console.log(`Rice制作完成,价格${this.price},耗时${this.time}分钟`);
        }
    }
    // 对原材料进行加工
    switch (name) {
        case "Steak":
            goods = new Steak()
            break
        case "Noodles":
            goods = new Noodles()
            break
        case "Grill":
            goods = new Grill()
            break
        case "Rice":
            goods = new Rice()
            break
    }
    // 出厂
    return goods
}
let a = shop("Steak");
let b = shop("Noodles");
let c = shop("Grill");
let d = shop("Rice");

a.done()
b.done()
c.done()
d.done()

此时虽然我们将代码逻辑进行了一个集中,但是同样面临一个问题,当我们需要新增一些工厂类的时候,需要在工厂函数中创建类实例并且,需要加case,很麻烦。如果逻辑比较复杂 ,代码会变得比较臃肿

//先来看一下 无共性的代码
//开放一个对外的窗口
let Shop = (function () {
    const SHOP = {
        //无共性
        a: class {
            constructor() {
                this.a = 1
                this.b = 2
            }
        },
        b: class {
            constructor() {
                this.aa = 1
                this.bb = 2
            }
        },
        c: class {
            constructor() {
            }
            log() {
                console.log("sb");
            }
        },
        d: class {
            constructor() {
                this.a = 666
            }
        }
    }
    return class {
        constructor(n) {
           return new SHOP[n]()
        }
    }
})()
let a = new Shop("a");
let b = new Shop("b");
let c = new Shop("c");
let d = new Shop("d");
console.log(a);
console.log(b);
console.log(c);
console.log(d);
// 当代码具有共性 我们需要提取公共的部分
let Shop = (function () {
    const SHOP = {
        Grill() {
            this.price = 20
            this.time = 15
        },
        Steak() {
            this.price = 50
            this.time = 20
        },
        Noodles() {
            this.price = 15
            this.time = 5
        },
        //新增产品 只需要修改这一步
        Rice() {
            this.price = 10
            this.time = 5
        }
    }
    return class {
        constructor(name) {
            this.name = name
            if (SHOP[name]) {
                SHOP[name].call(this) //将SHOP的this指向当前实例的this
            } else {
                // 处理报错的情况
                throw new Error("需要的餐品不存在")
            }
        }
		// 公共部分 相同
        done() {
            console.log(`${this.name}制作完成,价格${this.price},耗时${this.time}分钟`);
        }
    }
})()
let a = new Shop("Steak")
let b = new Shop("Grill")
let c = new Shop("Noodles")
let d = new Shop("Rice")
a.done()
b.done()
c.done()
d.done()

这个时候 后续每次新增只需要在SHOP工厂类中增加对应的属性就行了,而无需书写额外的代码,提高了代码的维护性。

如果需要给工厂类中增加一些没有共性的,可以增加一个参数,用来控制是否具有共性,从而执行后续的产出代码~

let Shop = (function () {//自调用函数 返回值决定其类型
        const SHOP = {
            //有共性
            Grill() {
                this.price = 20
                this.time = 15
            },
            Steak() {
                this.price = 50
                this.time = 20
            },
            Noodles() {
                this.price = 15
                this.time = 5
            },
            //新增产品 只需要修改这一步
            Rice() {
                this.price = 10
                this.time = 5
            },
            //新增一个没有共性的
            Goudan: class {
                constructor() {
                    this.name = "狗蛋"
                    this.age = 18
                }

                aa() {
                    console.log(11);
                }

                bb() {
                    console.log(22);
                }
            }
        }
        return class {//产出
            constructor(n, mode) {
                if (mode) return new SHOP[n]()//对于新增的没有共性的方法 将在                 这里导出
                this.name = n
                if (SHOP[n]) {
                    SHOP[n].call(this)//将SHOP的this指向这个this
                } else {
                    throw new Error("需要的餐品不存在")
                }
            }

            done() {
                console.log(`${this.name}制作完成,价格${this.price},耗时${this.time}分钟`);
            }
        }
    }
)()
let a = new Shop("Steak")
let b = new Shop("Grill")
let c = new Shop("Noodles")
let d = new Shop("Rice")
let f = new Shop("Goudan", true)
a.done()
b.done()
c.done()
d.done()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

貂蝉的腿毛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值