TypeScript實現設計模式——工廠模式


上回用typescript實現了單例模式,這回來實現工廠模式。工廠模式又分為簡單工廠模式、工廠方法模式以及抽象工廠模式。

簡單工廠模式

簡單工廠模式通常在業務比較簡單的情況下使用,它有三個部分組成:工廠類、抽象產品類、具體產品類。

抽象產品類

abstract class Pizza {
  public abstract show(): void;
  public abstract cut(): void;
}

具體產品類

class KFCPizza extends Pizza {
  public show(): void {
    console.log('This is KFCPizza!');
  }
  public cut(): void {
    console.log('Cut KFCPizza!');
  }
}

class MCPizza extends Pizza {
  public show(): void {
    console.log('This is MCPizza!');
  }
  public cut(): void {
    console.log('Cut MCPizza!');
  }
}

工廠類

class PizzaFactory {
  /**
   * 靜態工廠方法
   * @param pizzaType 限制傳入的參數為類,而非類的實例
   */
  public static createPizza(pizzaType: new () => Pizza): Pizza {
    let pizza = null;

    try {
      pizza = new pizzaType();
    } catch (e) {
      console.error('Create failed!');
    }

    return pizza;
  }
}

測試

let pizza = PizzaFactory.createPizza(KFCPizza);
pizza.show();

pizza = PizzaFactory.createPizza(MCPizza);
pizza.show();

工廠方法模式

正常情況下,簡單工廠模式每次增加新的產品都需要在工廠類中增加對應的邏輯,這樣就違背了開閉原則(但因為ts和我舉的例子的原因體現不出這個缺點)。工廠方法模式就解決了這個問題,同時它能更好的解決復雜的業務環境。

工廠方法模式具有四個部分:抽象工廠類、具體工廠類、抽象產品類、具體產品類。

抽象產品類

abstract class Pizza {
  public abstract show(): void;
  public abstract cut(): void;
}

具體產品類

class KFCPizza extends Pizza {
  public show(): void {
    console.log('This is KFCPizza!');
  }
  public cut(): void {
    console.log('Cut KFCPizza!');
  }
}

class MCPizza extends Pizza {
  public show(): void {
    console.log('This is MCPizza!');
  }
  public cut(): void {
    console.log('Cut MCPizza!');
  }
}

抽象工廠類

abstract class PizzaFactory {
  public abstract createPizza(): Pizza;
}

具體工廠類

class KFCPizzaFactory extends PizzaFactory {
  public createPizza(): Pizza {
    try {
      return new KFCPizza();
    } catch (error) {
      console.log(error);
    }
  }
}

class MCPizzaFactory extends PizzaFactory {
  public createPizza(): Pizza {
    try {
      return new MCPizza();
    } catch (error) {
      console.log(error);
    }
  }
}

測試

let factory: PizzaFactory = new KFCPizzaFactory();
let pizza = factory.createPizza();
pizza.show();

當我們需要增加新的產品時,只需要增加對應的工廠類而不需要更改原本工廠類內部的邏輯,完全符合了開閉原則。

抽象工廠模式

學習抽象工廠模式之前,首先要先了解兩個概念:產品等級結構產品族

  • 產品等級結構

    產品等級結構即產品的繼承結構,例如抽象的披薩類和具體某品牌的披薩類之間就構成了一個產品等級結構。

  • 產品族

    位於不同產品等級結構中的一組產品,功能相關聯的產品組成的家族,如KFC水果披薩、MC水果披薩都是水果披薩,就可以放到同一個產品族中。

抽象工廠模式具有和工廠方法模式一樣的四個部分:抽象工廠類、具體工廠類、抽象產品類、具體產品類。

抽象產品類

// KFC產品父類
abstract class KFCPizza {
  public abstract show(): void;
  public abstract cut(): void;
}

// MC產品父類
abstract class MCPizza {
  public abstract show(): void;
  public abstract cut(): void;
}

具體產品類

// 具體KFCPizza類
class KFCFruitPizza extends KFCPizza {
  public show(): void {
    console.log('This is KFCFruitPizza!');
  }
  public cut(): void {
    console.log('Cut KFCFruitPizza!');
  }
}

class KFCCheesePizza extends KFCPizza {
  public show(): void {
    console.log('This is KFCCheesePizza!');
  }
  public cut(): void {
    console.log('Cut KFCCheesePizza!');
  }
}

// 具體KFCPizza類
class MCFruitPizza extends MCPizza {
  public show(): void {
    console.log('This is MCFruitPizza!');
  }
  public cut(): void {
    console.log('Cut MCFruitPizza!');
  }
}

class MCCheesePizza extends MCPizza {
  public show(): void {
    console.log('This is MCCheesePizza!');
  }
  public cut(): void {
    console.log('Cut MCCheesePizza!');
  }
}

抽象工廠類

abstract class PizzaFactory {
  public abstract createKFCPizza(): KFCPizza;
  public abstract createMCPizza(): MCPizza;
}

具體工廠類

// 水果披薩工廠
class FruitPizzaFactory extends PizzaFactory {
  public createKFCPizza(): KFCPizza {
    try {
      return new KFCFruitPizza();
    } catch (error) {
      console.log(error);
    }
  }
  public createMCPizza(): MCPizza {
    try {
      return new MCFruitPizza();
    } catch (error) {
      console.log(error);
    }
  }
}

// 芝士披薩工廠
class CheesePizzaFactory extends PizzaFactory {
  public createKFCPizza(): KFCPizza {
    try {
      return new KFCCheesePizza();
    } catch (error) {
      console.log(error);
    }
  }
  public createMCPizza(): MCPizza {
    try {
      return new MCCheesePizza();
    } catch (error) {
      console.log(error);
    }
  }
}

測試

let factory: PizzaFactory = new CheesePizzaFactory();
let cheesePizza = factory.createKFCPizza();
cheesePizza.show();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM