工廠模式包括:簡單工廠模式,工廠方法模式伍宦,抽象工廠模式
簡單工廠模式
工廠方法根據(jù)參數(shù)直接創(chuàng)建實例:工廠->產(chǎn)品
一個人開了個咖啡館芽死,賣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('本店不支持');
}
}
// 簡單工廠:工廠方法直接創(chuàng)建實例
createCoffeeFactory('AmericanoCoffee');
createCoffeeFactory('LatteCoffee');
代碼非常簡單关贵,但是如果新增一樣咖啡時,要擴展一個咖啡種類Cuppuccino卖毁,同時createCoffeeFactory的switch里面要新增一個case坪哄。
違法開閉原則:對擴展開發(fā),對修改關(guān)閉。什么是擴展翩肌,什么是修改?
// 新增一個類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');
工廠方法模式
抽象一個工廠方法,具體的工廠創(chuàng)建產(chǎn)品
抽象工廠->具體工廠->一種產(chǎn)品
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();
}
}
// 具體工廠創(chuàng)建產(chǎn)品
new AmericanoCoffeeFactory().createCoffee();
new LatteCoffeeFactory().createCoffee();
此時碍侦,如果要增加卡布奇諾咖啡粱坤,要擴展一個工廠和一種咖啡
// 擴展一個咖啡
class CuppuccinoCoffee{
constructor() {
console.log('LatteCoffee');
}
}
// 擴展一個工廠
class CuppuccinoCoffeeFactory extends CoffeeFactory {
createCoffee() {
new CuppuccinoCoffee();
}
}
// 客戶端下單卡布奇諾
new CuppuccinoCoffeeFactory().createCoffee();
相比簡單工廠模式,克服了簡單工廠的缺點瓷产。
抽象工廠模式
但是假如這家咖啡廳是星巴克,客人要點瑞幸的咖啡時,怎么辦首妖?
我們把咖啡分成:星巴克美式炫贤,星巴克拿鐵,瑞幸美式尔邓,瑞幸拿鐵
和工廠方法對區(qū)別晾剖,增加對咖啡種類進行抽象。這里涉及到產(chǎn)品族和產(chǎn)品種類的概念梯嗽。
星巴克和瑞幸是產(chǎn)品族齿尽,美式和拿鐵是產(chǎn)品種類。是2個維度的概念灯节。
抽象產(chǎn)品->實現(xiàn)產(chǎn)品
抽象工廠->實現(xiàn)工廠->生產(chǎn)多種產(chǎn)品
// 和工廠方法模式的區(qū)別:對咖啡種類進行抽象
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');
}
}
// 和工廠方法模式的區(qū)別:一個工廠要做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抽象類循头,兩個產(chǎn)品族分別擴展CuppuccinoCoffee實現(xiàn)類,抽象工廠要增加(修改)做卡布奇諾的抽象方法炎疆,具體工廠要增加(修改)做卡布奇諾的實現(xiàn)方法卡骂。
此時,抽象工廠的缺點也暴露出來磷雇。增加一個產(chǎn)品種類時偿警,擴展有1+n個,修改有1+n個唯笙。n是產(chǎn)品族的個數(shù)
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();
}
// 增加實現(xiàn)方法
createCuppuccinoCoffee(){
new StarbuckCuppuccinoCoffee();
}
}
class LuckinCoffeeFactory extends CoffeeFactory {
createAmericanoCoffee() {
new LuckinAmericanoCoffee();
}
createLattaCoffee() {
new LuckinLatteCoffee();
}
// 增加實現(xiàn)方法
createCuppuccinoCoffee(){
new LuckinCuppuccinoCoffee();
}
}
new StarbuckCoffeeFactory().createAmericanoCoffee();
new StarbuckCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createAmericanoCoffee();
new LuckinCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createCuppuccinoCoffee();
總結(jié):
- 簡單工廠模式:
工廠-產(chǎn)品
優(yōu)點:簡單
缺點:違法開閉原則 - 工廠方法模式:
抽象工廠-實現(xiàn)工廠-一種產(chǎn)品
優(yōu)點:克服簡單工廠的缺點
缺點:面對產(chǎn)品族和產(chǎn)品種類問題時螟蒸,不夠抽象 - 抽象工廠模式:
抽象產(chǎn)品-具體產(chǎn)品
抽象工廠-具體工廠-多種產(chǎn)品
優(yōu)點:針對多個產(chǎn)品族和多個產(chǎn)品種類時,相對來說能抽象清晰的表達多個維度的關(guān)系崩掘;拓展產(chǎn)品族時七嫌,遵循開閉原則
缺點:擴展產(chǎn)品種類時,無法很好地做到開閉原則苞慢。需要1+n個修改