美文网首页
设计模式-3种工厂模式

设计模式-3种工厂模式

作者: 小麻烦爱学习 | 来源:发表于2021-02-22 00:15 被阅读0次

工厂模式包括:简单工厂模式,工厂方法模式,抽象工厂模式

简单工厂模式

工厂方法根据参数直接创建实例:工厂->产品

一个人开了个咖啡馆,卖2种咖啡:美式咖啡、拿铁。

class AmericanoCoffee {
    constructor() {
        console.log('AmericanoCoffee');
    }
}
class LatteCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
function createCoffeeFactory(name: string) {
    switch (name) {
        case 'AmericanoCoffee':
            return new AmericanoCoffee();
        case 'LatteCoffee':
            return new LatteCoffee();
        default:
            return new Error('本店不支持');
    }
}
// 简单工厂:工厂方法直接创建实例
createCoffeeFactory('AmericanoCoffee');
createCoffeeFactory('LatteCoffee');

代码非常简单,但是如果新增一样咖啡时,要扩展一个咖啡种类Cuppuccino,同时createCoffeeFactory的switch里面要新增一个case。
违法开闭原则:对扩展开发,对修改关闭。什么是扩展,什么是修改?

// 新增一个类CuppuccinoCoffee,就是扩展
class CuppuccinoCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
function createCoffeeFactory(name: string) {
    switch (name) {
        case 'AmericanoCoffee':
            return new AmericanoCoffee();
        case 'LatteCoffee':
            return new LatteCoffee();
        case 'CuppuccinoCoffee': // 修改了原有的代码,就是修改
            return new CuppuccinoCoffee()
        default:
            return new Error('本店不支持');
    }
}
createCoffeeFactory('CuppuccinoCoffee');

工厂方法模式

抽象一个工厂方法,具体的工厂创建产品
抽象工厂->具体工厂->一种产品

class AmericanoCoffee {
    constructor() {
        console.log('AmericanoCoffee');
    }
}
class LatteCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
// 抽象工厂
abstract class CoffeeFactory {
    abstract createCoffee();
}
// 具体工厂
class AmericanoCoffeeFactory extends CoffeeFactory {
    createCoffee() {
        new AmericanoCoffee()
    }
}
class LatteCoffeeFactory extends CoffeeFactory {
    createCoffee() {
        new LatteCoffee();
    }
}
// 具体工厂创建产品
new AmericanoCoffeeFactory().createCoffee();
new LatteCoffeeFactory().createCoffee();

此时,如果要增加卡布奇诺咖啡,要扩展一个工厂和一种咖啡

// 扩展一个咖啡
class CuppuccinoCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
// 扩展一个工厂
class CuppuccinoCoffeeFactory extends CoffeeFactory {
    createCoffee() {
        new CuppuccinoCoffee();
    }
}
// 客户端下单卡布奇诺
new CuppuccinoCoffeeFactory().createCoffee();

相比简单工厂模式,克服了简单工厂的缺点。

抽象工厂模式

但是假如这家咖啡厅是星巴克,客人要点瑞幸的咖啡时,怎么办?
我们把咖啡分成:星巴克美式,星巴克拿铁,瑞幸美式,瑞幸拿铁
和工厂方法对区别,增加对咖啡种类进行抽象。这里涉及到产品族和产品种类的概念。
星巴克和瑞幸是产品族,美式和拿铁是产品种类。是2个维度的概念。
抽象产品->实现产品
抽象工厂->实现工厂->生产多种产品

// 和工厂方法模式的区别:对咖啡种类进行抽象
abstract class AmericanoCoffee {
}
abstract class LatteCoffee{
}

class StarbuckAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('StarbuckAmericanoCoffee');
    }
}
class StarbuckLatteCoffee extends LatteCoffee{ 
    constructor() {
        super();
        console.log('StarbuckLatteCoffee');
    }
}
class LuckinAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('LuckinAmericanoCoffee');
    }
}
class LuckinLatteCoffee extends LatteCoffee{
    constructor() {
        super();
        console.log('LuckinLatteCoffee');
    }
}
// 和工厂方法模式的区别:一个工厂要做2种咖啡
abstract class CoffeeFactory {
    abstract createAmericanoCoffee();
    abstract createLattaCoffee();
}

class StarbuckCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new StarbuckAmericanoCoffee();
    }
    createLattaCoffee() {
        new StarbuckLatteCoffee();
    }
}
class LuckinCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new LuckinAmericanoCoffee();
    }
    createLattaCoffee() {
        new LuckinLatteCoffee();
    }
}

new StarbuckCoffeeFactory().createAmericanoCoffee();
new StarbuckCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createAmericanoCoffee();
new LuckinCoffeeFactory().createLattaCoffee();

此时要增加卡布奇诺咖啡种类,那么要扩展CuppuccinoCoffee抽象类,两个产品族分别扩展CuppuccinoCoffee实现类,抽象工厂要增加(修改)做卡布奇诺的抽象方法,具体工厂要增加(修改)做卡布奇诺的实现方法。
此时,抽象工厂的缺点也暴露出来。增加一个产品种类时,扩展有1+n个,修改有1+n个。n是产品族的个数

abstract class AmericanoCoffee {
}
abstract class LatteCoffee{
}
// 扩展咖啡种类
abstract class CuppuccinoCoffee{
}

class StarbuckAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('StarbuckAmericanoCoffee');
    }
}
class StarbuckLatteCoffee extends LatteCoffee{ 
    constructor() {
        super();
        console.log('StarbuckLatteCoffee');
    }
}
// 星巴克扩展
class StarbuckCuppuccinoCoffee extends CuppuccinoCoffee{ 
    constructor() {
        super();
        console.log('StarbuckCuppuccinoCoffee');
    }
}
// 瑞幸扩展
class LuckinAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('LuckinAmericanoCoffee');
    }
}
class LuckinLatteCoffee extends LatteCoffee{
    constructor() {
        super();
        console.log('LuckinLatteCoffee');
    }
}
class LuckinCuppuccinoCoffee extends CuppuccinoCoffee{
    constructor() {
        super();
        console.log('LuckinCuppuccinoCoffee');
    }
}

abstract class CoffeeFactory {
    abstract createAmericanoCoffee();
    abstract createLattaCoffee();
    // 增加抽象方法
    abstract createCuppuccinoCoffee();
}

class StarbuckCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new StarbuckAmericanoCoffee();
    }
    createLattaCoffee() {
        new StarbuckLatteCoffee();
    }
    // 增加实现方法
    createCuppuccinoCoffee(){
        new StarbuckCuppuccinoCoffee();
    }
}
class LuckinCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new LuckinAmericanoCoffee();
    }
    createLattaCoffee() {
        new LuckinLatteCoffee();
    }
    // 增加实现方法
    createCuppuccinoCoffee(){
        new LuckinCuppuccinoCoffee();
    }

}

new StarbuckCoffeeFactory().createAmericanoCoffee();
new StarbuckCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createAmericanoCoffee();
new LuckinCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createCuppuccinoCoffee();

总结:

  1. 简单工厂模式:
    工厂-产品
    优点:简单
    缺点:违法开闭原则
  2. 工厂方法模式:
    抽象工厂-实现工厂-一种产品
    优点:克服简单工厂的缺点
    缺点:面对产品族和产品种类问题时,不够抽象
  3. 抽象工厂模式:
    抽象产品-具体产品
    抽象工厂-具体工厂-多种产品
    优点:针对多个产品族和多个产品种类时,相对来说能抽象清晰的表达多个维度的关系;拓展产品族时,遵循开闭原则
    缺点:扩展产品种类时,无法很好地做到开闭原则。需要1+n个修改

相关文章

  • 设计模式四、抽象工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 抽象工厂模式 ...

  • 工厂模式

    java设计模式-工厂模式 工厂模式: 工厂模式是java设计模式里最常用的设计模式之一。 工厂模式属于创建型模式...

  • 设计模式之工厂模式

    设计模式之工厂模式 标签(空格分隔): 设计模式 工厂模式 设计模式的感念 设计模式的应用 工厂设计模式的产生 工...

  • 设计模式三、工厂模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 工厂模式 在一...

  • 设计模式一、单例模式

    系列传送门设计模式一、单例模式设计模式二、简单工厂模式设计模式三、工厂模式设计模式四、抽象工厂模式 简单单例(推荐...

  • 单件设计模式

    一、定义 设计模式 设计模式就是一种更好的编写代码方案。 常见设计模式 工厂设计模式、抽象工厂设计模式、抽象工厂设...

  • iOS设计模式(三)之抽象工厂模式

    设计模式系列传送门 iOS设计模式(一)之简单工厂模式iOS设计模式(二)之工厂模式iOS设计模式(三)之抽象工厂...

  • iOS设计模式(一)之简单工厂模式

    设计模式系列传送门 iOS设计模式(一)之简单工厂模式iOS设计模式(二)之工厂模式iOS设计模式(三)之抽象工厂...

  • iOS设计模式(二)之工厂模式

    设计模式系列传送门 iOS设计模式(一)之简单工厂模式iOS设计模式(二)之工厂模式iOS设计模式(三)之抽象工厂...

  • 常用设计模式

    设计模式 工厂模式 工厂模式思路上分:简单工厂模式,工厂模式, 抽象工厂模式// 抽象工厂模式可以代替工厂模式,做...

网友评论

      本文标题:设计模式-3种工厂模式

      本文链接:https://www.haomeiwen.com/subject/ltacfltx.html