JavaScript简单工厂模式原理与实战:解决弹窗类设计痛点

作者:闭包旅人时间:2026-10-23 17:22:45浏览:194

本文深入解析JavaScript中的简单工厂模式,通过弹窗工具类的重构案例,展示如何消除冗长的if-else逻辑。文章详细阐述了如何将对象创建与使用分离,利用静态工厂方法集中管理实例创建,从而满足单一职责与开闭原则,提升代码的可维护性与扩展性。

本文通过具体实例解析JavaScript中的简单工厂模式,旨在为读者提供可参考的实践方案。

简单工厂模式定义与基础

简单工厂模式是创建型设计模式中最常见的一种。尽管它未被列入GoF(Gang of Four)的23种经典设计模式中,但它是理解其他复杂工厂模式的重要基础。

该模式定义了一个工厂类,根据传入参数的不同返回不同的实例对象。这些被创建的实例通常共享同一个父类。由于创建实例的方法通常被定义为静态方法,因此简单工厂模式也被称为静态工厂方法模式,属于类创建型模式。

应用场景与现有设计缺陷

考虑一个实际场景:开发一个对话框(Dialog)工具类。在项目初期,可能只需要实现一个简单的弹窗;但随着项目迭代,需求会衍生出多种类型的弹窗,例如带有关闭按钮的、带有确认按钮的等。

常见的做法是根据一个type值来判断当前需要创建哪种类型的窗口。虽然这种设计看似直观,但结合前述的设计原则进行分析,会发现其存在明显的缺陷。

主要缺点包括: 1. 代码中存在多个if...else...代码块,导致代码冗长,增加了阅读、维护和测试的难度,并可能影响系统性能。 2. Dialog类职责过重,负责初始化所有类型的弹窗实例,这违反了单一职责原则,不利于代码的重用和维护。 3. 当需要新增弹窗类型时,必须修改现有源代码,这违反了开闭原则。 4. 由于不同种类的弹窗基础样式相似,会导致大量重复代码的存在。 5. 各类弹窗的创建和使用分散在各个业务逻辑中,若需修改创建方式,必须修改所有相关的业务代码,再次违反了开闭原则。

以下是具体的解决方案示例。

基于工厂模式的解决方案实现


var Dialog = (function(){
  var createNotice = function(){
    return '<div>notice</div>';
  }
  var createToast = function(){
    return '<div>toast</div>';
  }
  var createWarnin = function(){
 return '<div>warnin</div>';
  }
  var Dialog = function(){
 this.element = '';
 this.name = '';
 this.show = function(){
   console.log(this.name + ' is show -> ' + this.element);
 };
  }
 
  return {
 factory: function(arg){
   var _dialog;
   if(arg === 'notice'){
     _dialog = new Dialog();
     _dialog.element = createNotice();
     _dialog.name = 'notice';
     }else if(arg === 'toast'){
     _dialog = new Dialog();
     _dialog.element = createToast();
     _dialog.name = 'toast';
   }else if(arg === 'warnin'){
     _dialog = new Dialog();
     _dialog.element = createWarnin();
     _dialog.name = 'warnin';
   }
   return _dialog;
 }
  }
})();
 
var notice = Dialog.factory('notice');
var toast = Dialog.factory('toast');
var warnin = Dialog.factory('warnin');
toast.show(); //toast is show -> <div>toast</div>
notice.show(); //notice is show -> <div>notice</div>
warnin.show(); //warnin is show -> <div>warnin</div>

上述解决方案基于个人理解编写,并参考了Java的示例。实现方式多样,可以使用原型链或继承等方式,但本文重点探讨为何采用这种设计思路。

针对之前列出的5个缺点,本方案主要解决了第2、4和5点。通过将共有的方法和属性抽取到父类中,减少了重复代码;将每种情况特有的代码单独抽取,解决了不符合单一职责原则的问题。

关键点在于将所有弹窗的创建逻辑集中到工厂类中。当需要修改创建逻辑时,只需修改工厂类即可,而无需影响现有的业务代码。

这里需要思考两个问题:1. 如何彻底去除那些if...else...逻辑? 2. 当需要新增一个error类型的弹窗时,如何满足开闭原则?

经过尝试,得出以下实现方式。

优化后的代码结构与开闭原则


var Dialog = function(){
  this.element = '';
  this.name = '';
  this.show = function(){
 console.log(this.name + ' is show -> ' + this.element);
  };
}
 
Dialog.createNotice = function(){ return '<div>notice</div>'; };
Dialog.createToast = function(){ return '<div>toast</div>'; };
Dialog.createWarnin = function(){ return '<div>warnin</div>'; };
Dialog.factory = function(arg){ 
  var _dialog = new Dialog();
  _dialog.element = Dialog[arg]();
  _dialog.name = arg;
  return _dialog;
};
 
var notice = Dialog.factory('createNotice');
var toast = Dialog.factory('createToast');
var warnin = Dialog.factory('createWarnin');
notice.show(); //createNotice is show -> <div>notice</div>
warnin.show(); //createWarnin is show -> <div>warnin</div>
toast.show(); //createToast is show -> <div>toast</div>

通过这种方式,新增功能时只需添加一条配置即可,无需修改公告内容。这完美满足了开闭原则,即对扩展开放,对修改关闭。

模式优缺点与适用场景总结

简单工厂模式的总结如下。

优点: * 简单工厂模式实现了对象创建和使用的分离,降低了耦合度。

缺点: * 工厂类集中了所有产品的创建逻辑,职责过重。一旦工厂类出现问题,可能会影响整个系统。

适用场景: * 适用于创建的对象数量较少的情况,因为对象较少,不会导致工厂方法中的业务逻辑过于复杂。 * 客户端只需知道传入工厂类的参数,无需关心具体的对象创建过程。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码的运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》。

希望本文所述的简单工厂模式应用案例能对大家的JavaScript程序设计有所帮助。

作者最新文章

相关标签: