实时

您的位置:首页>企业 >

三言两语说透设计模式的艺术-工厂方法模式

工厂方法模式通过面向对象封装了对象创建过程,实现低耦合、高内聚的代码,给系统提供了灵活的产品扩展方式,是非常流行与常用的设计模式。

1写在前面

前面写到简单工厂模式虽然比较简单,将实例的创建和使用分类,客户端只需使用由工厂类创建的对象即可,无需关心对象的创建过程。但是这个系统仍然存在问题:


【资料图】

1)工厂类过于庞大,包含了大量的if判断语句代码,导致维护和测试难度增加;

2)当前只存在一个工厂类,在需要添加新产品时,由于静态工厂方法通过传入参数创建不同的产品,必须修改工厂了的源码,违背了开闭原则。

对此,需要对简单工厂模式进行优化,使其具有更好的灵活性和扩展性。这也是工厂方法模式的由来。

2工厂方法模式

工厂方法模式(Factory Method Pattern)是简单工厂模式的进一步抽象和推广。在工厂方法模式中,不再提供一个统一的工厂类来创建所有的产品对象,而是针对不同产品提供不同的工厂,使每个工厂只负责创建对应的产品。

工厂方法模式,是对简单工厂模式进行重构,即定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。

工厂方法模式包含以下主要角色:

抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问产品。具体工厂(ConcreteFactory):实现了抽象工厂接口,完成具体产品的创建。抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间往往存在依赖关系。

工厂方法模式的主要优点:

封装了产品创建过程,调用者只需关心所需产品类型。实现了开闭原则,增加新产品无需修改之前工厂类代码。调用者无需知道产品类名,实现解耦,符合依赖倒转原则。易于扩展新产品,满足开闭原则,增加新产品仅需新增一个具体产品类和具体工厂类,无需修改现存代码。

可能的缺点:

每增加一个产品就需要增加一个具体工厂,导致系统中类的个数成倍增加。复杂产品需要对应复杂工厂类,不易维护。

3工厂方法模式的实现

我们使用 Typescript 代码来实现一个简单的工厂方法模式:

首先定义抽象产品类和具体产品类:

interface Food {  getType(): string;}class Hamburger implements Food {  getType() {    return "Hamburger";  }}class Hotdog implements Food {  getType() {    return "Hotdog";  }}

然后是抽象工厂类和具体工厂类:

abstract class FoodFactory {  abstract createFood(): Food;}class HamburgerFactory extends FoodFactory {  createFood() {    return new Hamburger();  }}class HotdogFactory extends FoodFactory {  createFood() {    return new Hotdog();  }}

客户端代码:

const hamburgerFactory = new HamburgerFactory();const hamburger = hamburgerFactory.createFood();const hotdogFactory = new HotdogFactory();const hotdog = hotdogFactory.createFood();

客户端通过具体工厂来获取需要的产品,不关心实际产品类名。

在抽象工厂中使用泛型

我们可以使用泛型来定义产品类型:

interface FoodFactory {  createFood(): T; }// 实现时指定泛型class HamburgerFactory implements FoodFactory {  // ...}

这样可以使工厂方法返回类型更加明确。

将工厂抽象成函数

工厂方法也可以简单实现为函数:

function createFood(type: "Hamburger" | "Hotdog") {  switch(type) {    case "Hamburger":       return new Hamburger();    case "Hotdog":      return new Hotdog();  }}

这种方式更简单,降低了代码的复杂度,但缺少面向对象的灵活性。

工厂方法模式 vs 简单工厂模式

简单工厂模式中工厂类负责所有产品的创建;而工厂方法模式中每一个具体工厂类只负责创建对应的一个产品,它将产品的创建推迟到子类。

两者区别主要在:

简单工厂中,工厂类负责所有产品创建。工厂方法中,每个具体工厂只负责对应的产品。工厂方法模式更加灵活,易扩展,但创建对象较多。

简单工厂适合产品种类少的情况,工厂方法适合产品不断扩展的场景。

应用实例:游戏工厂

我们可以使用工厂方法模式实现一个游戏工厂,用于生成不同类型的游戏对象。

首先是游戏基类和具体游戏类:

interface Game {  start();}class RPG implements Game {  start() {    console.log("Starting RPG game");  } }class MMORPG implements Game {  start() {    console.log("Starting MMORPG game");  }}

然后是抽象工厂和具体工厂:

abstract class GameFactory {  abstract createGame(): Game;}class RPGFactory extends GameFactory {  createGame() {    return new RPG();  }}class MMORPGFactory extends GameFactory {  createGame() {   return new MMORPG();   }}

客户端代码:

const rpgFactory = new RPGFactory();const rpgGame = rpgFactory.createGame();rpgGame.start();const mmorpgFactory = new MMORPGFactory();const mmorpgGame = mmorpgFactory.createGame();mmorpgGame.start();

客户端只需要关心游戏类型,而不关心具体类名。

4总结

工厂方法模式是一种广泛使用的设计模式,它具有以下核心特点:

抽象工厂类负责定义创建对象的接口,而由子类实现CreateObject方法,实现了责任分解。每个具体工厂类只负责创建对应的一个产品,一个工厂类对应一个产品类。调用者只需要关心所需产品的类型,无需知道产品类名,实现了解耦。易于扩展新产品,满足开闭原则,当新增产品时只要增加一个具体工厂和产品类,无需修改之前代码。典型应用场景是针对同一抽象产品类有多个具体产品类的情况,而系统需要根据环境情况动态获得不同的具体产品对象。相比简单工厂模式,工厂方法模式更加灵活,易扩展,但创建对象较多。

综上,工厂方法模式通过面向对象封装了对象创建过程,实现低耦合、高内聚的代码,给系统提供了灵活的产品扩展方式,是非常流行与常用的设计模式。

关键词:

推荐阅读
工厂方法模式通过面向对象封装了对象创建过程,实现低耦合、高内聚的代

2023-08-06 06:25:01

hello大家好,我是城乡经济网小晟来为大家解答以上问题,穷兵赎武与穷

2023-08-06 04:11:36

很多人对车评头条:阿斯顿马丁DB5Junior是一款售价42,000英镑不是很了

2023-08-06 00:49:37

资薪金支出账载金额,账载金额和税收金额是什么意思这个问题很多朋友还

2023-08-05 22:00:36

中新网武汉8月4日电(梁婷李雯雯)在鄂港资企业政企沟通圆桌会议4日在

2023-08-05 21:22:50

1、水苔是栽培蝴蝶兰比较常见的介质,同时对于栽培蝴蝶兰的容器选择也

2023-08-05 20:01:35

盛夏,骄阳似火,走在路上,衣服湿了又干,干了又湿。巩义市公安局交警

2023-08-05 18:55:41

新华社成都8月4日电(记者陈地)4日,成都大运会赛事运行专场新闻发布

2023-08-05 17:44:41

很多人对车评头条:我们希望英国成为拥有超低排放汽车的世界上最好的地

2023-08-05 17:03:51

作为中国古代的四大古都之一,西安拥有丰富的历史文化遗产和自然景观,

2023-08-05 15:59:48

8月5日上午,镇平县雪枫中学2023级新生入学面试工作正式启动。该校为高

2023-08-05 14:52:14

提起内蒙古的优秀女演员,可能大家都只想得起斯琴高娃吧,她确实是十分

2023-08-05 13:44:03

来源:第一财经当地时间周五,美国三大股指冲高回落,最终全线收跌。美

2023-08-05 12:52:05

央视网消息:8月2日以来,黑龙江省哈尔滨、牡丹江、伊春、齐齐哈尔4个

2023-08-05 11:49:08

,你们好,今天0471房产来聊聊一篇子兵法与现代经济运筹,子兵法与现代

2023-08-05 10:55:51

继阿里清仓式减持后,港股上市公司商汤又被大股东软银减持了。根据港交

2023-08-05 10:12:29

8月4日21时,国家减灾委、应急管理部针对黑龙江严重暴雨洪涝灾害,启动

2023-08-05 09:39:43

佳士科技(股票代码:300193)在2023年08月08日新增可售A股442 6063万

2023-08-05 09:05:29

8月5日,思特威发布股份减持公告,股东BrizanChinaHoldingsLimited,Fo

2023-08-05 07:45:06

直播吧8月5日讯据转会专家迪马济奥透露,萨勒尼塔纳希望租借尤文球员米

2023-08-05 06:36:10