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

如何通过模板模式重构代码?

时间:2023-03-20 10:59:59 科技观察

大家好,我是北军。本文为大家介绍一种日常开发中常用的设计模式——模板模式。1.什么是模板模式在操作中定义算法的骨架,将一些步骤推迟到子类。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。模板方法模式:在中定义一个算法的运行框架,将一些步骤推迟到子类中。这允许子类在不改变算法结构的情况下重新定义算法的一些特定步骤。说人话:父类模板方法定义一个不变的过程,子类重写过程中的方法。二、模板模式定义1、AbstractClass抽象模板①基本方法上面的baseOperation()或customOperation()方法,也叫基本操作,是子类实现的方法,在模板方法中调用。基本方法尽量设计成保护类型,符合迪米特定律,不需要暴露的属性或方法尽量不要设置成保护类型。如果实现类不是必须的,尽量不要在父类中扩展访问权限。②模板方法之上的templateMethod()方法可以有一个或几个方法来实现基本方法的调度,完成固定逻辑。为了防止恶意操作,模板方法通常会加上final关键字,并且不允许覆盖。2、ConcreteClass具体模板实现了父类定义的一个或多个抽象方法,即父类定义的基本方法在子类中实现。3.模板模式的通用代码publicabstractclassAbstractClass{//常见且繁琐的操作privatevoidbaseOperation(){//dosomething}//子类自定义的操作protectedabstractvoidcustomOperation();//模板方法定义框架publicfinalvoidtemplateMethod(){/***调用基础方法完成固定逻辑*/baseOperation();自定义操作();}}publicclassConcreteClass1extendsAbstractClass{@OverrideprotectedvoidcustomOperation(){//具体模板1业务逻辑System.out.println("Specifictemplate1:customOperation()");}}publicclassConcreteClass2extendsAbstractClass{@OverrideprotectedvoidcustomOperation(){//具体模板2业务逻辑System.out.println("具体模板2:customOperation()");}}测试:publicclassTemplateClient{publicstaticvoidmain(String[]args){AbstractClassabstractClass1=newConcreteClass1();抽象类abstractClass2=newConcreteClass2();应用模板(abstractClass1);应用模板吃了(abstractClass2);}publicstaticvoidapplyTemplate(AbstractClassabstractClass){abstractClass.templateMethod();}}4.模板方式的优点1.封装不变部分,扩展可变部分,将算法视为不变部分封装到父类实现中,而可变部分可以通过继承继续扩展2.抽取共性部分代码便于维护3.行为由父类控制,子类实现的基本方法由子类实现,所以子类可以通过扩展方式添加相应的功能,符合原则打开和关闭。五、模板模式的缺点1、子类执行的结果会影响父类的结果,这与我们平时的设计习惯是相反的。在复杂的项目中,会带来阅读困难。2.可能导致子类激增和为了继承而继承的问题6.回调为了解决模板模式的缺点,我们可以使用回调函数来代替子类继承。publicinterfaceCallback{voidcustomOperation();}publicclassSubCallbackimplementsCallback{@OverridepublicvoidcustomOperation(){System.out.println("SubCallbackcustomOperation");}}/***模板类*声明为final,不能继承*/publicfinalclassTemplate{privatevoidbaseOperation(){System.out.println("模板类公共操作");}publicvoidtemplateMethod(Callbackcallback){baseOperation();回调.customOperation();}}测试:publicclassTemplateClient{publicstaticvoidmain(String[]args){Templatetemplate=newTemplate();应用模板(模板);}publicstaticvoidapplyTemplate(Templatetemplate){回调callback=newSubCallback();模板。模板方法(回调);}}Template是一个稳定的final类,不能被继承,不存在子类的行为影响父类结果的问题。Callback是一个接口,为了继承而继承的问题就迎刃而解了。