这是《小游戏从0到1设计模式重构》系列内容第7篇,所有源码及资料在“程序员LIYI”公号回复“小游戏从0到1”获取。
看完三姐妹中的简单工厂模式,再看看二姐工厂方法模式。因为在简单工厂模式中,我们为了创建一个名称为createPage的静态方法,侵入了Page基类,这是不优雅的。按照开放-封闭原则(OCP),好的设计是对扩展开放,对修改封闭,那么如何避免对原有对象代码的侵入呢?使用继承可以,于是就有了工厂方法模式。
在工厂方法模式中,我们新建一个新类PageFactory,继承于Page(当然有时候也可以不继承),并在这个新类中实现创建对象的静态方法。看代码:
代码语言:javascript复制// page/page_factory.js
import Page from './page'
import IndexPage from './index_page'
import GameOverPage from './game_over_page'
class PageFactory extends Page {
// 创建页面对象
static createPage(pageName){
let page
switch (pageName) {
case "index":
page = new IndexPage()
break;
case "gameOver":
default:
page = new GameOverPage()
break;
}
return page
}
}
export default PageFactory
注意,我们在PageFactory中引入IndexPage、GameOverPage这两个页面子类的方式,是通过ES6 Module规范实现的;而上一小节在Page中引用这两个页面子类,却只能通过支持运行时导入的CommonJS规范实现。如果在父类Page中通过ES6 Module规范引入Page页面的子类(同时子类又继承于父类),这势必会造成循环引用的尴尬。
再看一下在game.js中如何使用,与使用Page.createPage一样简单:
代码语言:javascript复制// game.js
...
import PageFactory from './page/page_factory'
...
class Game extends Event {
...
constructor() {
...
// this.gameOverPage = Page.createPage("gameOver")
// this.indexPage = Page.createPage("index")
this.gameOverPage = PageFactory.createPage("gameOver")// 游戏结束页面
this.indexPage = PageFactory.createPage("index") // 主页
}
...
}
运行效果与之前一致:
阶段源码
本小节阶段源码见:disc/第五章/5.1.7。
我讲明白没有,欢迎提问。
2021年1月30日
本文视频: