设计模式之工厂方法

1. 定义

在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型

2. 口语化举例

工厂里组装台灯,流程、配件等有多种方式,每种台灯有自己的生产线

现在,需要某一种台灯,但暂时不知道是哪一种,一种方式是想清楚了再去找工厂生产

另一种方式是先去和工厂联系好,支付定金,工厂给出一张购买凭证,想清楚需要什么台灯时,就可以直接兑换

这流程有一定的好处,就是拿到购买凭证过后,我就象征性的拥有了台灯,虽然现在还没有具体实物,拿着这个凭证,可以去干拥有台灯才能干的事,比如零售台灯

这就是工厂方法模式,虽然创建时暂时还没有具体对象,但是拥有随时创建具体对象的能力

下面的描述会沿用这个上述这个场景

3. 源码示例

Cesium.js是一个著名的、基于WebGL的GIS前端框架

基于WebGL就不得不提WebGL(OpenGL)的基础概念,比如Shader、Shader Program等

Cesium中有频繁的Shader Program创建操作,源码中封装了ShaderProgram类,其中createAndLinkProgram(gl, shader)函数实现了创建

Shader Program是多种多样的,所以Cesium将最后实例化的ShaderProgram交给子类来确定

值得一说的是,在Cesium中,真正的ShaderProgram对象是直到需要绘制时才创建,不需要绘制的就不会创建,这样有效节省了资源:

function beginDraw() {
  // ...
  shaderProgram.createAndLinkProgram(gl, shader);
}

4. 总结

4.1 设计原则

  • 单一职责原则

    每个生产线只负责生产自己的产品,前台只负责通知调度,职责明确

  • 开闭原则

    要添加新的产品线只需告诉前台即可

4.2 适用场景

  • 无法预知对象确切类别及其依赖关系时, 可使用工厂方法

    无法确定具体生产什么,所以需要客户自己确定并告知工厂生产线

  • 构建能扩展的软件库或框架的内部组件, 可使用工厂方法

    前台的存在使得要添加新的产品线只需告诉前台即可

  • 复用现有对象来节省系统资源, 而不是每次都重新创建对象, 可使用工厂方法

    前台具有拦截并调度的作用,如果要生产的产品有库存,前台可以直接交付给客户,无需再告诉生产线

5. 参考资料

[1] 工厂方法设计模式 (refactoringguru.cn)

[2] Cesium渲染模块之Shader - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)

posted @ 2023-10-31 01:13  当时明月在曾照彩云归  阅读(7)  评论(0编辑  收藏  举报