当前位置: 首页 > 科技观察

Typescript设计模式之工厂方法

时间:2023-03-19 15:55:51 科技观察

本文转载自微信公众号《全栈修真之路》,作者阿宝哥。转载本文请联系全栈修真之路公众号。在现实生活中,工厂负责生产满足我们日常生理需求的产品,如牛奶、面包或礼品等。另外,在我们的日常生活中,我们离不开大大小小的系统,它们是由不同的组件对象组成的。作为一名网络软件开发工程师,我们可以在软件系统的设计和开发过程中使用设计模式来提高代码的可重用性、可扩展性和可维护性。在众多设计模式中,有一种设计模式称为工厂模式,它提供了创建对象的最佳方式。工厂模式可以分为三类:简单工厂模式工厂方法模式抽象工厂模式本文将介绍简单工厂模式和工厂方法模式,而抽象工厂模式将在后续文章中介绍。先介绍一下简单工厂模式。一、简单工厂模式1.1简单工厂模式简介简单工厂模式也称为静态方法模式,因为在工厂类中定义了一个静态方法用于创建对象。简单工厂允许用户在不知道具体参数的情况下创建所需的“产品”类,即用户可以在不知道产品具体生产细节的情况下直接消费产品。相信对于刚刚接触简单工厂模式的小伙伴来说,上面的描述可能会觉得有些抽象。在此,为了让小伙伴们更好的了解简单工厂模式,阿宝哥以用户购买汽车为例,介绍一下宝马工厂是如何使用简单工厂模式进行生产的。上图中,阿宝哥模拟了用户的购车流程。平安和qhw分别向宝马工厂订购BMW730和BMW840车型,工厂根据相应车型进行生产,生产完成后交付给用户。接下来,阿宝哥将介绍如何用一个简单的工厂来描述宝马工厂生产指定型号汽车的过程。1.2简单工厂模式定义BMW抽象类abstractclassBMW{abstractrun():void;}创建BMW730类(BMW730Model)classBMW730extendsBMW{run():void{console.log("BMW730start");}}创建BMW840类(BMW730Model)840Model)classBMW840extendsBMW{run():void{console.log("BMW840starts");}}创建BMWFactory工厂类classBMWFactory{publicstaticproduceBMW(model:"730"|"840"):BMW{if(model==="730"){returnnewBMW730();}else{returnnewBMW840();}}}生产并推出BMW730和BMW840constbmw730=BMWFactory.produceBMW("730");constbmw840=BMWFactory.produceBMW("840");bmw730.run();bmw840.run();运行上面的代码后的输出是:BMW730startsupBMW840startsup通过观察上面的输出结果,我们可以知道我们的BMWFactory已经正常工作了。在BMWFactory类中,阿宝哥定义了一个produceBMW()方法,该方法会根据传入的模型参数创建不同模型的汽车。看完了简单工厂模式的实际例子,是不是觉得简单工厂模式还是挺容易理解的。那么在什么场景下使用简单工厂模式呢?要回答这个问题,我们需要了解简单工厂的优缺点。1.3简单工厂模式优缺点1.3.1优点将创建实例的任务和使用实例的任务分开,用户无需关心对象是如何创建的,实现了系统的解耦;客户端不需要知道创建的具体产品类的类名,只需要知道具体产品类对应的参数即可。1.3.2缺点由于工厂类集中了所有的产品创建逻辑,一旦不能正常工作,将会影响到整个系统。系统难以扩展。添加新产品后,必须修改工厂逻辑。当产品种类较多时,工厂逻辑可能过于复杂,不利于系统扩展和维护。了解了简单工厂的优缺点之后,我们再来看看它的应用场景。1.4简单工厂模式应用场景如果满足以下条件可以考虑使用简单工厂模式:工厂类负责创建较少的对象:由于创建的对象比较小,工厂方法中的业务逻辑不会太多复杂的。客户端只需要知道传入工厂类静态方法的参数,不需要关心对象创建的细节。简单工厂模式介绍完了,我们来介绍一下本文的主角,“工厂方法模式”。2.工厂??方法模式2.1工厂方法简介工厂方法模式(FactoryMethodPattern)又称工厂模式,又称为多态工厂(PolymorphicFactory)模式,属于类创建模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生成具体的产品对象。这样做的目的是延迟产品类到工厂子类的实例化。也就是说,工厂子类用于确定应该实例化哪个具体的产品类。上图中,阿宝哥模拟了用户的购车流程。平安和qhw分别向宝马730和宝马840工厂订购了BMW730和BMW840车型,工厂根据相应车型生产交付给用户。下面阿宝哥就给大家介绍一下如何使用工厂方法来描述宝马工厂生产指定型号汽车的过程。2.2工厂方法定义BMW抽象类abstractclassBMW{abstractrun():void;}创建BMW730类(BMW730Model)classBMW730extendsBMW{run():void{console.log("BMW730start");}}创建BMW840类(BMW840Model)classBMW840extendsBMW{run():void{console.log("BMW840starts");}}定义BMWFactory接口interfaceBMWFactory{produceBMW():BMW;}创建BMW730Factory类classBMW730FactoryimplementsBMWFactory(Bnew{Wurret3M():BMW);}}创建BMW840Factory类classBMW840FactoryimplementsBMWFactory{produceBMW():BMW{returnnewBMW840();}}生产并发动BMW730和BMW840constbmw730Factory=newBMW730Factory();constbmw840Factory=newBMW840Factory();constbmw730=bmw730Factory.produceBMW();constbmw840=bmw840Factory.produceBMW();bmw730.run();bmw840.run();通过观察上面的输出结果,我们可以知道我们的BMW730Factory和BMW840Factory工厂已经正常工作了。与之前的简单工厂模式相比,工厂方法模式通过创建不同的工厂来生产不同的产品。让我们来看看工厂方法的优点和缺点。2.3工厂方法的优缺点2.3.1优点在系统中添加新产品时,不需要修改抽象工厂提供的接口和抽象产品,只需添加具体的工厂和具体的产品即可。这样,系统的扩展性就变得很好,也更符合“开闭原则”。简单工厂模式需要修改工厂类的判断逻辑。本着单一职责的原则,即每个具体的工厂类只负责创建对应的产品。简单工厂模式中的工厂类有一定的逻辑判断。基于工厂角色和产品角色的多态设计是工厂方法模式的关键。它使工厂能够独立决定创建什么产品对象,如何创建这个对象的细节完全封装在具体的工厂中。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都有同一个抽象父类。2.3.2缺点添加新产品时,需要写一个新的具体产品类别,并提供相应的具体工厂类别。系统中的类别数量会成对增加,这在一定程度上增加了系统的复杂度,需要编译运行的类比较多,会给系统带来一些额外的开销。特定的工厂只能生产特定的产品。最后简单介绍一下工厂方法的应用场景。2.4工厂方法应用场景一个类不知道它需要的对象的类:在工厂方法模式下,客户端不需要知道具体产品类的类名,只需要知道对应的工厂即可。具体的产品对象由具体的工厂类创建;客户需要知道创建具体产品的工厂类。一个类通过其子类指定创建哪个对象:在工厂方法模式中,抽象工厂类只需要提供创建产品的接口,其子类决定具体创建的对象,采用面向对象的多态性性质和里氏代换原则,程序运行时,子类对象会覆盖父类对象,使得系统更容易扩展。3.参考资源简单工厂模式(SimpleFactoryPattern)设计模式-simple_factoryFactory方法模式(FactoryMethod)