当前位置: 首页 > 后端技术 > Java

设计模式[13]--如何获取模板模式?

时间:2023-04-01 23:27:44 Java

开场还是一样的画面,所有嘉宾都往下看……张无忌学太极拳,招式全忘了,打败了“玄冥二老”,所谓“心无招数””。设计模式可以说是技巧。如果先学会各种模式,忘掉所有模式,随心所欲,可谓OO的最高境界。什么是模板模式?模板模式也是一种行为模式,即关于对象做什么或如何做的设计模式。模板模式的本质是需要在运算中定义算法的框架,但是有一些步骤不需要具体实现,而是不同的子类分别实现。子类不能修改流程框架,但可以自定义一些步骤。主要问题是解决了一些通用的方法,但是每个子类都要重写,冗余。比如做菜的步骤一般是:洗锅-->油炸-->洗菜,不同的菜品,但是做菜的步骤具体细节是不一样的,但是其他的步骤确实是几乎一模一样的,所以在事实上整体框架,以及重复的步骤,我们可以将它们抽象成模板,不同的细节方法可以开放给每个菜品(具体实现)进行定制。再比如盖房子,很多地方的施工都是一样的:地基、墙壁、水管等等,但是不同房子的内部设计是不一样的。挑一个不使用模板模式的“炒菜”的简单例子。如果不使用模板模式,糖醋鲤鱼:publicclassSweetAndSourCarp{publicvoidcookFood(){washPan();厨师();吃();洗碗();System.out.println("");}privatevoidwashPan(){System.out.print("Washpan-->");}privatevoidcook(){System.out.print("煮糖醋鲤鱼-->");}privatevoideat(){System.out.print("Eat-->");}privatevoidwashDishes(){System.out.print("洗碗-->");}}再做一个小农家的炸猪肉,需要写很多相同的方法:厨师();吃();洗碗();System.out.println("");}privatevoidwashPan(){System.out.print("Washthepan-->");}privatevoidcook(){System.out.print("炒农家小炒肉-->");}privatevoideat(){System.out.print("Eat--&g吨;");}privatevoidwashDishes(){System.out.print("Washingdishing-->");}}测试类如下:publicclassTest{publicstaticvoidmain(String[]args){SweetAndSourCarpsweetAndSourCarp=newSweetAndSourCarp();sweetAndSourCarp.cookFood();ShreddedPorkWithVegetablesshreddedPorkWithVegetables=newShreddedPorkWithVegetables();shreddedPorkWithVegetables.cookFood();->洗锅-->炒农家小炒肉-->吃-->洗碗-->可以看到整体流程是一样的,有些步骤相同,有些步骤不同,但是你不用模板模式,需要每个类都重写方法。即使它是通用方法,整个流程需要自己写,使用模板模式优化,如果使用模板模式,那么我们会抽象一个抽象类来定义整体流程,固定步骤,开放需求。自定义方法允许具体实现类根据自己的需要定制。定义抽象类:publicabstractclassCookFood{publicfinalvoidcookFood(){washPan();厨师();吃();洗碗();System.out.println("");}privatefinalvoidwashPan(){System.out.print("洗锅-->");公共抽象无效厨师();privatefinalvoideat(){System.out.print("Eat-->");}privatefinalvoidwashDishes(){System.out.print("洗碗-->");}}具体实现类糖醋鲤鱼:}}农家小炒肉:publicclassShreddedPorkWithVegetablesextendsCookFood{@Overridepublicvoidcook(){System.out.print("Friedfarmhousesmallfriedpork-->");}}测试类和前面一样,测试结果也一样,这里不再赘述。在上面的方法中,其实我们只开启了cook()方法,也就是hook方法:在模板方法模式的父类中,我们可以定义一个方法,默认什么都不做,子类可以重写视情况而定,这种方法称为“挂钩法”。hook方法是开放的,可以被子类随意覆盖,但是和上面的其他方法一样,我们不希望子类覆盖或者覆盖它,所以我们可以使用final关键字来防止子类覆盖模板方法。模板模式的应用实际上是在JDK的Thread实现中使用的。我们知道创建线程有两种方式:创建一个Thread类实现runnable接口。我们一般实现run()方法,而是调用start()方法来启动线程。原因是start()方法帮我们调用了run()方法。run()方法是开发出来的方法,我们可以覆盖重写。Start0()是native方法,由C语言实现。调用的时候,其实是调用了我们的run()方法。如果需要跟踪这个方法,需要到HotSpot底层。这里介绍的目的是让大家知道它也是使用模板模式。私有原生voidstart0();native关键字的理解可以参考:http://aphysia.cn/archives/na...模板模式的优缺点模板模式的优缺点:1.封装固定的部分,对需要的地方进行扩展定制和修改部分,符合开闭原则。2、公共代码在父类中,易于维护。3.全程由父类控制,调整更方便。缺点:1.可能有很多子类,增加了系统的复杂度。2.只实现了子类的一小部分。要理解所有的方法,需要在父类中阅读,影响代码阅读。总结:代码中应该隐藏的复杂细节隐藏了,自定义部分打开了,优雅!设计模式系列:设计模式【1】--单例模式有几种写法?设计模式【1.1】——你想如何打破单例模式?设计模式【1.2】--枚举单例这么好用?设计模式[1.3]--Hungry式单例为什么是线程安全的?设计模式[2]--看简单工厂模式?设计模式[2.1]--简单工厂模式是如何演变成工厂方法模式的?设计模式[2.2]--工厂模式是如何演变成抽象工厂模式的?设计模式[3.1]--浅谈代理模式之静态、动态、cglib代理设计模式[3.2]--JDK动态代理源码解析有多香?设计模式[3.3]--CGLIB动态代理源码解释设计模式[4]--建造者模式设计模式详解[5]--原型模式设计模式[6.1]--适配器模式设计模式初探[6.2]]--浅谈适配器模式设计模式[7]--探究桥接模式设计模式[8]--手把手教我写装饰器模式设计模式[9]--外观模式?没那么高端的设计模式[10]——顺便看看享元模式设计模式[11]——get组合模式设计模式[12]——get已经流行起来的策略模式最近【作者简介】:秦淮,公众号【秦淮杂货店】作者,个人网站:http://aphysia.cn,技术之路不是一时的,山高水长,哪怕再慢,也不会停下。剑指全题OfferPDF开源编程笔记