【7/25】使用工厂方法模式(Factory Method Pattern)创建Page页面对象

2021-02-23 16:05:31 浏览数 (1)

这是《小游戏从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日

本文视频:

0 人点赞