前言我们上次介绍了单例模式。没看过的朋友可以看这个链接:JS设计模式浅析:单例模式今天说一个常见的设计模式:工厂模式。工厂模式是一种创建对象的创建模式,遵循DRY(Don'tRepeatYourself)原则。在这种模式下,代码将根据特定的输入或其他既定规则来决定创建哪种类型的对象。简单的说就是动态返回需要的实例对象。回顾上一个例子,让我们继续使用单例模式下的例子,一个日志记录工具Logger:classLogger{log(...args){console.log(...args);}}以上是核心API,每次使用都需要用newLogger()创建一个logger对象,然后和console一样使用~各种Logger如果我们现在的代码支持electron环境,即log可以是consolelog也可以是loggerfilelog,那么我们需要两种logger:ConsoleLogger//logger/console.jsclassConsoleLogger{log(...args){console.log(...args)}}exportdefaultConsoleLoggerFileLogger//logger/file.jsclassFileLogger{log(...args){dumpLog(...args)}}exportdefaultFileLogger这里不用关心dumpLog的具体实现,只管知道就是把日志写到文件里~使用我们工厂里已经有两种logger,但这两种logger的API其实是一样的。当然也可以在项目中直接导入使用,但是每次需要导入对应类型的模块,然后使用,像这样:UseconsoleloggerimportConsoleLoggerfrom'./logger/console'constlogger=newConsoleLogger()UsefileloggerimportFileLoggerfrom'./logger/file'constlogger=newFileLogger()是不是很麻烦?如果还有其他的logger类型,比如remotelogs,就会有更多的使用方式。为了统一logger模块的使用,这时候就要用到工厂模式了~让我们新建一个index.js://logger/index.jsimportConsoleLoggerfrom'./console.js'importFileLoggerfrom'./file.js'functioncreateLogger(type='console'){if(type==='console'){returnnewConsoleLogger()}elseif(type==='file'){returnnewFileLogger()}thrownewError(`Loggertypenotfound:${type}`)}exportdefaultcreateLogger好了,现在我们的用法会变成这样:importcreateLoggerfrom'./logger'//consoleloggerconstlogger1=createLogger('console')//fileloggerconstlogger2=createLogger('file')重构上面的ifelse是不是很优雅?添加更多记录器类型是否很麻烦?那么我们就可以使用对象来映射它,从而舍弃ifelse,同时增加一个logger选项。//logger/index.jsimportConsoleLoggerfrom'./console.js'importFileLoggerfrom'./file.js'constloggerMap={console:ConsoleLogger,file:FileLogger}//可选参数一般放在函数createLogger的末尾(options,type='console'){constLogger=loggerMap[type]if(Logger){returnnewLogger(options)}thrownewError(`Loggertypenotfound:${type}`)}上面的封装在其实它也符合SOLID原则中的开闭原则,即对扩展开放,对修改关闭。每当我们添加一个记录器类型时,我们只需要添加一个新文件,然后将构造函数注册到loggerMap中。.和外面的使用方式一样,以最少的修改完成功能的添加。在运行时确定对象类型的情况。抽象:封装了对象创建的细节,用户不会接触到对象的构造函数,只需要告诉工厂需要什么样的对象即可。易用性/可维护性:用工厂管理相似的对象,提供统一的创建接口,满足开闭原则,让我们无需修改大量代码就可以轻松添加多种类型的对象。好~!工厂模式的介绍就到此结束啦~下次我们讲装饰器模式~参考内容JavaScriptObjectOrientedPatterns:FactoryPattern《JavaScript 设计模式》《JavaScript 面向对象编程指南》
