[设计模式]一看就懂的工厂模式

230 阅读3分钟

「这是我参与2022首次更文挑战的第34天,活动详情查看:2022首次更文挑战

简单工厂模式

简单工厂是由一个工厂对象来决定创建哪一种产品类的实例

类图

image.png

我们以购买宠物为例,其中猫,狗,鸭都是Pet的子类,当我们消费者要买宠物时,宠物店会根据顾客的需求来提供对应的宠物类。

代码

abstract class Pet {
    constructor(public name:string) {
        this.name = name
    }
}

class Dog extends Pet{}

class Cat extends Pet{}

class Duck extends Pet{}

class PetFactory{
   static choose(name:string){
       switch (name){
           case 'dog':
               return new Dog('dog');
           case  'cat':
               return new Cat('cat');
           case  'duck':
               return new Duck('duck');
           default:
               throw new Error('你要的宠物暂无')
       }
   }
}

console.log(PetFactory.choose('dog'))
console.log(PetFactory.choose('cat'))
console.log(PetFactory.choose('duck'))
console.log(PetFactory.choose('fish'))

我们看看效果

image.png

优缺点

  • 优点:将对象的公用属性抽离到一个构造函数中,通过构造函数配合switch实现返回不同的对象。

  • 缺点:当有很多的种类时,需要写很多的case,当需要新增种类时,需要添加case,就违反了封闭原则。

经典场景

jQuery

image.png

接下来,我们使用简单工厂模式来实现一下

interface jQuery{
    [index:number]:any
}

class jQuery {
    length:number
    constructor(selector:string) {
        let elements = Array.from(document.querySelectorAll(selector))
        let length = elements ? elements.length : 0
        this.length = length
        for(let i =0;i<length;i++){
            this[i] = elements[i]
        }
    }
    html(htmlText:string|undefined){
        if(htmlText){
            for(let i =0;i<length;i++){
                this[i].innerHTML = htmlText
            }
        }else {
            return  this[0].innerHTM
        }
    }
}
interface Window{
    $:any
}
window.$ = function (selector:string){
    return new jQuery(selector)
}

React

createElement将不同类型的元素返回不同类型的元素的实例。

简而言之,简单工厂模式就是函数里返回类的实例。

工厂方法模式

  • 工厂方法模式Factory Method,闭包又称多态性工厂模式。
  • 在工厂方法模式中,核心的工厂类不再负责所有的实例的创建,而是将具体创建的工作交给子类去做。

类图

image.png

从图中我们可以看出,当我们需要对用的猫、狗、鸭时,都是由其对应的工厂类来创建实例。

代码

abstract class Pet {
    constructor(public name:string) {
        this.name = name
    }
}

class Dog extends Pet{}

class Cat extends Pet{}

class Duck extends Pet{}

abstract class PetFactory{
    abstract createPet():Pet
}

class DogFactory extends PetFactory{
    createPet(){
        return new Dog('dog');
    }
}

class CatFactory extends PetFactory{
    createPet(){
        return new Cat('cat');
    }
}

class DuckFactory extends PetFactory{
    createPet(){
        return new Duck('duck');
    }
}

class Factory{
    static choose(name:string){
        switch (name){
            case 'dog':
                return new DogFactory().createPet();
            case  'cat':
                return new CatFactory().createPet();
            case  'duck':
                return new DuckFactory().createPet();
            default:
                throw new Error('你要的宠物暂无')
        }
    }
}

console.log(Factory.choose('dog'))
console.log(Factory.choose('cat'))
console.log(Factory.choose('duck'))
console.log(Factory.choose('fish'))

经典场景

React

抽象工厂模式

  • 抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象
  • 工厂方法模式针对的是同一类或者同一产品,而抽象工厂模式针对的是多种类的产品设计
  • 系统中有多个产品族,每个具体工厂负责创建同一族但属于不同产品等级(种类)的产品
  • 产品族是一组相关或相互依赖的对象
  • 系统一次只能消费某一族产品,即相同产品族的产品是一起被使用的
  • 当系统需要新增一个产品族时,只要新增新的工厂类即可,无需修改源代码
  • 如果要从产品族中新增一个新种类的产品时,则所有的工厂类都要修改

组成角色

  • 抽象工厂: 提供了创建产品的接口,包含多个创建产品的方法
  • 具体工厂: 实现抽象工厂定义的接口,完成某个具体产品的创建
  • 抽象产品: 抽象产品定义,一般有多少抽象产品,抽象工厂中就有多少创建产品的方法
  • 具体产品: 抽象产品的实现类

类图

image.png

代码

abstract class Dog {}
abstract class Cat {}
abstract class Duck {}

class MaleDog extends Dog{}
class FemaleDog extends Dog{}
class MaleCat extends Cat{}
class FemaleCat extends Cat{}
class MaleDuck extends Duck{}
class FemaleDuck extends Duck{}

abstract class PetFactory {
    abstract createDog():Dog
    abstract createCat():Cat
    abstract createDuck():Duck
}

class MalePetFactory extends PetFactory{
    createDog(){
        return new MaleDog()
    }
    createCat(){
        return new MaleCat()
    }
    createDuck(){
        return new MaleDuck()
    }
}

class FemalePetFactory extends PetFactory{
    createDog(){
        return new FemaleDog()
    }
    createCat(){
        return new FemaleCat()
    }
    createDuck(){
        return new FemaleDuck()
    }
}

const malePetFactory = new MalePetFactory()
console.log(malePetFactory.createDog())

最后

以上就是工厂模式的简单介绍,希望能对你有所帮助。