TypeScript中的工厂设计模式

TypeScript中的工厂设计模式

TypeScript编写工厂模式:

工厂模式简单来说就是一个工厂(用于创建其它类的实例的类),多种产品(实际需要的类的实例),常见的又分为简单工厂模式与工厂方法模式

一、简单工厂
简单工厂:简单工厂又名静态工厂,以创建实例的方法为静态方法而得名。
简单工厂聚合了不同类的实例化工作,将实例化的工作从实际的业务代码中剥离,
		只需要调用该类,传入对应的参数得到对应的实例化对象。

简单工厂的角色

抽象产品类:coffee
具体实现抽象产品类的产品子类:Latte, Moca, Cappuccino 
生产具体产品实例的工厂类:coffeeFactory
// 定义一个抽象的 Coffee 类。
abstract class Coffee {
    name:string 
    show() {
        console.log(`this is ${this.name}`);
      }
}

// Coffee 具体实现类 Latte
class Latte extends Coffee {
    constructor(){
        // 由于继承了抽象类,需要调用 super 来获取 this 
        super() 
        this.name = 'Latte'
    }
}

// Coffee 具体实现类 Moca
class Moca extends Coffee{
    constructor(){
        super()
        this.name = 'Moca'
    }
}

// Coffee 具体实现类 Cappuccino
class Cappuccino extends Coffee{
  constructor(){
      super()
      this.name = 'Cappuccino'
  }
}


// 工厂类
class CoffeeFactory {
  // 静态方法获取相应的对象实例
  static getCoffee(type?: string): Coffee {
    // 根据传入参数,判断应该返回什么样的实例给调用方
    switch (type) {
      case "latte":
        return new Latte()
      case "moca":
        return new Moca();
        case "cappuccino":
          return new Cappuccino()
      default:
        console.log('no coffee provided')
        return;
    }
  }
}
实现原理:
在代码中如果需要生成某一个具体的抽象产品的子类,我们就需要自己实例化类,如果在实例化一个对象的过程中,
需要重复很多动作,将会造成代码冗余,可读性很差,所以需要一个工厂来生成实例,只需要告知工厂需要什么,
就生成什么实例化对象

优点与缺点:

优点:工厂类中包括创建实例对象的工作,在调用的时候,不再需要关心实例化的具体细节和创建任务的条件判断,
		调用方只需要知道参数即可,业务方无需关心具体实例化的细节。
		工厂类里面包含了所有类的实例化逻辑
缺点:工厂类中有所有类的实例化的逻辑,所以如果要新增加一个类,就需要新增加一个类目,就需要修改工厂类
			不符合设计原则中的开闭原则。
			简单工厂就是静态方法来创建实例的,导致工厂类无法形成继承的的等级结构

使用场景:在创建的对象比较少,对象的逻辑不复杂的时候

二、工厂方法
工厂方法:就是将简单工厂进一步抽象,工厂类不再创建产品的任务,而是把创建产品的任务交给工厂子类来创建

工厂方法的角色

抽象产品类:Coffee
具体的子类:Latte, Moca, Cappuccino
核心工厂:CoffeeFactory
具体实现抽象工厂的工厂子类 :ChinaFactory,JanpanFactory
// 定义一个抽象的 myCoffee 类。
abstract class myCoffee {
    name:string 
    show() {
        console.log(`this is ${this.name}`);
      }
}

// myCoffee 具体实现类 myLatte
class myLatte extends myCoffee {
    constructor(){
        // 由于继承了抽象类,需要调用 super 来获取 this 
        super() 
        this.name = 'myLatte'
    }
}

// myCoffee 具体实现类 myMoca
class myMoca extends myCoffee{
    constructor(){
        super()
        this.name = 'myMoca'
    }
}

// myCoffee 具体实现类 myCappuccino
class myCappuccino extends myCoffee{
  constructor(){
      super()
      this.name = 'Cappuccino'
  }
}





// 改造上一小节的 myCoffeeFactory 改造为一个抽象工厂,核心工厂类
abstract class myCoffeeFactory {
    name: string;
    mycoffee:myCoffee;
    abstract myproduceCoffee(): void;
    mygetCoffeeList() {
      console.log(`${this.name} can produce: `);
    //   this.mycoffee.getName()
    }
  }
  
  // 具体实现核心工厂类的 日本工厂子类
  class JapanCoffeeFactory extends myCoffeeFactory {
    constructor(name: string) {
      super();
      this.name = name;
    }
    myproduceCoffee() {
      // 创建咖啡子类 myLatte 实例
      this.mycoffee = new myLatte()
    }
  }
  
  // 具体实现核心工厂类的 中国工厂子类
  class ChinaCoffeeFactory extends myCoffeeFactory {
    constructor(name: string) {
      super();
      this.name = name;
    }
    myproduceCoffee() {
      // 创建咖啡子类 myMoca 实例
      this.mycoffee = new myMoca()
    }
  }
  
  const China = new ChinaCoffeeFactory("shenzhen");
  const Japan = new JapanCoffeeFactory("toshita");
  China.myproduceCoffee();
  China.mygetCoffeeList(); // 业务方获取中国工厂生产的 myMoca 咖啡实例
  
  Japan.myproduceCoffee(); 
  Japan.mygetCoffeeList(); // 业务方获取日本工厂生产的 myLatte 咖啡实例

优点与缺点:

优点:相比起简单工厂,在加入新产品时,都需要修改工厂类;采用工厂模式则可以无需修改抽象工厂和抽象产品的接口,
只需要提供一个具体的工厂和具体产品即可,提高了系统的可扩展性。
满足单一职责原则,工厂类不再判断和创建一系列的工作,只是定义好了创建对象的接口,
由工厂子类负责生产具体的产品对象,每个具体工厂生产具体的产品;将实例化的操作延迟至不同的工厂子类中完成。
缺点:每个具体工厂只能生产具体的一种产品

使用场景:

1.所创建的类不需要知道它所依赖的具体的对象类,只需要知道所属的工厂即可,具体的产品对象由具体的工厂创建
2.	工厂类只需要一个创建产品的接口,具体的工厂子类是来确定和实现具体要创建的对象,将创建具体产品的任务交
	给子类工厂。
3.降低了代码耦合度,对象的生成交给子类去完成,实现了开放封闭原则 - 每次添加子产品 不需要修改原有代码
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值