前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【8/25】使用抽象工厂模式(Abstract Factory Pattern) 封装页面对象的创建过程

【8/25】使用抽象工厂模式(Abstract Factory Pattern) 封装页面对象的创建过程

作者头像
LIYI
发布2021-02-23 16:05:17
3960
发布2021-02-23 16:05:17
举报
文章被收录于专栏:艺述论专栏艺述论专栏

这是《小游戏从0到1设计模式重构》系列内容第8篇,所有源码及资料在“程序员LIYI”公号回复“小游戏从0到1”获取。

看完了三姐妹中的大姐、二姐,最后看一下三妹抽象工厂模式。

在工厂方法模式中,虽然避免了对Page类的侵入,但是返回的对象却是具体的子页面类型(IndexPage或GameOverPage)。根据依赖倒置原则,要面向接口编程,不要面向具体实现编程。接下来我们将实现一个新类AbstractPageFactory,这个类不需要再继承于Page,也实现一个createPage静态方法,但是返回的对象却是“虚拟”的Page,而不是具体的IndexPage、GameOverPage或其它页面子对象的实例。js没有接口,也没有虚拟类,但此时为了说明概念,我们姑且假设它有。

先看一下AbstractPageFactory如何实现:

代码语言:javascript
复制
// page/abstract_page_factory.js
import Page from './page'
import IndexPage from './index_page'
import GameOverPage from './game_over_page'

class AbstractPageFactory{
  // 创建页面对象
  static createPage(pageName){
    let page = new Page()// of Page
    switch (pageName) {
      case "index":
        page = new IndexPage()
        break;
      case "gameOver":
      default:
        page = new GameOverPage()
          break;
    }
    return page 
  }
}
export default AbstractPageFactory

主要代码与之前Page.createPage与PageFactory.createPage的实现是基本一样的,为了说明返回的page对象是Page类型,我们特意引入Page基类,并对page变量作了默认实例化。虽然这样做毫无意义,因为我们在switch流程控制语句中有一个默认的default分支,它已经保证了page不为空。

再看一个game.js中的消费改动,与之前使用PageFactory是类似的:

代码语言:javascript
复制
// game.js
...
// import PageFactory from './page/page_factory'
import AbstractPageFactory from './page/abstract_page_factory'
...
class Game extends Event {
  ...
  constructor() { 
    ...
    // this.gameOverPage = PageFactory.createPage("gameOver")
    // this.indexPage = PageFactory.createPage("index")
    this.gameOverPage = AbstractPageFactory.createPage("gameOver")// 游戏结束页面
    this.indexPage = AbstractPageFactory.createPage("index") // 主页
  }
...
}

因为我们在实现抽象工厂模式之前,已经将Page页面对象子类化了,所以在这一小节的实现中,便不需要继承于Page实现两个子类(IndexPage和GameOverPage)了。而事实上如果这两个子类不存在,在这一小节我们是需要手动实现的。还有,在上一小节我们实现PageFactory时,也是直接使用具体的子类实例化页面对象的,而在一般情况下,这两个页面子类彼时尚不存在,只能通过实例化Page并修改其属性,以这样的方式达到创建对象的目的。

游戏的运行效果与之前一般无二:

最后总结一下,工厂三姐妹具有相同的目的和实现策略,只是抽象程度和自由程度不同而已,那么在开发中我们应该如何选择呢?

这里适合最简原则,当我们不明确应该如何选择的时候,采用最简单的同时又能满足需求的方案。具体在三个工厂模式中选择,如果简单工厂模式能解决,就不用工厂方法模式;如果工厂方法模式能解决,就不用抽象工厂模式。在我们目前这个至简的小游戏项目中,本来简单工厂模式就足够满足需求,所以后面两个模式的实现看起来总有些画蛇添足。

阶段源码

本小节阶段源码见:disc/第五章/5.1.8。

我讲明白没有,欢迎提问。

2021年1月30日

本文视频:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 艺述论 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 阶段源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档