大家好,我说的是北军。在软件开发的过程中,我们会用到很多设计模式,前面介绍过的单例模式,后面还会介绍代理模式、适配器模式、建造者模式等等。针对合适的场景使用合适的设计模式,你会发现业务逻辑会清晰很多。但是对于工厂模式,我奉劝大家,没事最好不要用。什么,为什么这么问?1、什么是工厂模式?定义用于创建对象的接口,但让子类决定实例化哪个类。工厂方法让类将实例化推迟到子类。定义一个创建对象的接口,让其子类决定实例化哪个工厂类,工厂模式将创建过程延迟到子类。说人话:提供创建对象的接口,屏蔽创建对象的过程,从而达到灵活的目的。2.工厂模式的分类工厂模式一般分为三类:①简单工厂②工厂方法③抽象工厂这三种模式从上到下逐渐抽象,更具有通用性。需要注意的是,GOF在书中将工厂模式分为两类《设计模式》:FactoryMethod和AbstractFactory,并将SimpleFactory视为工厂方法模式的一个特例,将两者归为一类。下面我们分别介绍这三种工厂模式。2.1以简单工厂(SimpleFactory)为例,有这样一个需求:根据不同的导入文件(docx、xlsx、pptx),选择不同的解析器进行解析。简单工厂有3个核心对象:Factory:简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类中创建产品类的方法可以被外界直接调用,创建需要的产品对象。.抽象产品:简单工厂模式创建的所有对象的父类,负责描述所有实例共享的公共接口。具体产品:是简单工厂模式的创建对象,所有创建的对象都是扮演这个角色的具体类的实例。①抽像解析器publicinterfaceIOfficeParser{voidparse();}②工具解析器(docx,xlsx,pptx)publicclassWordParserimplementsIOfficeParser{privateStringfilePath;publicWordParser(StringfilePath){this.filePath=filePath;}@Overridepublicvoidparse(){System.out.println("解析docx文件");}}publicclassExcelParser实现IOfficeParser{privateStringfilePath;publicExcelParser(StringfilePath){this.filePath=filePath;}@Overridepublicvoidparse(){System.out.println("解析xlsx文件");}}publicclassPptParserimplementsIOfficeParser{privateStringfilePath;publicPptParser(StringfilePath){this.filePath=filePath;}@Overridepublicvoidparse(){System.out.println("解析pptx文件");}}③构造解析器的工厂publicclassOfficeParserFactory{publicstaticIOfficeParsergetParser(StringfilePath)throwsException{StringfileExtension=getFileExtens离子(文件路径);IOfficeParser解析器=null;if("docx".equalsIgnoreCase(fileExtension)){parser=newWordParser(filePath);}elseif("xlsx".equalsIgnoreCase(fileExtension)){parser=newExcelParser(filePath);}elseif("pptx".equalsIgnoreCase(fileExtension)){parser=newPptParser(filePath);}else{thrownewException("不支持文件:"+fileExtension);}返回解析器;}privatestaticStringgetFileExtension(StringfilePath){//解析文件名获取文件扩展名,如document.docx,返回docxStringfileExtension=filePath.substring(filePath.lastIndexOf(".")+1);返回文件扩展名;}}④测试类publicclassSimpleFactoryTest{publicstaticvoidmain(String[]args)throwsException{StringfilePath="Document.docx";IOfficeParser解析器=OfficeParserFactory.getParser(filePath);解析器.parse();StringfilePath1="Table.xlsx";IOfficeParserparser1=OfficeParserFactory.getParser(filePath1);解析器1.解析();}}⑤综上所述,这是一个简单的工厂,客户端避免了直接创建解析器的责任,只需要调用工厂类进行解析即可。原理(对扩展开放,对修改关闭)分析简单工厂模式:当添加一个文件解析时,比如老版本的doc格式。这时候只需要添加一个解析器类,客户端(理解为测试类,调用者)不需要改变,然后在工厂类OfficeParserFactory中添加一个else-if分支。这时候可能有同学会问,那么修改OfficeParserFactory类,不是违反了开闭原则吗?但实际上,只要不经常添加新的解析器,偶尔修改OfficeParserFactory类,不符合开闭原则,也是可以的。公认。看起来很完美,细心的同学可能会问,所有的解析类对象都是在OfficeParserFactory类中创建的,假设是某个解析类,比如doc,创建一个解析器对象不是简单的new,还包括一些其他的操作,此时是否可以将这些代码全部写入OfficeParserFactory?有没有更优雅的写法?没错,就是下面要介绍的工厂模式。2.2工厂方法(FactoryMethod)为了解决以上问题,我们可以为工厂类创建一个工厂,也就是工厂的工厂,来创建工厂类对象。①为每个特定的解析器创建一个工厂publicclassExcelParserFactoryimplementsIOfficeParserFactory{@OverridepublicIOfficeParsercreateParser(){//TODO对对象创建执行一些操作}}②创建解析器工厂publicclassOfficeParserFactory{publicstaticIOfficeParsergetParser(StringfilePath)throwsException{StringfileExtension=getFileExtension(filePath);IOfficeParserFactoryparserFactory=OfficeParserFactoryMap.getOfficeParseFactory(fileExtension);if(parserFactory==null){thrownewException("不支持文件:"+file);}IOfficeParser解析器=parserFactory.createParser();返回解析器;}privatestaticStringgetFileExtension(StringfilePath){//解析文件名获取文件扩展名,如document.docx,返回docxStringfileExtension=filePath.substring(filePath.lastIndexOf(".")+1);返回文件扩展名;}}③创建解析器工厂的工厂类publicclassOfficeParserFactoryMap{privatestaticfinalMap
