您现在的位置是:主页 > 博文 > 福利专区 > 编程那点事 >

来聊聊封装继承多态的特征的JAVA设计模式,

2019-10-24 收藏 推荐 文章来源:借鉴作者:锤子

简介关心篮球或喜欢访问社交网站的朋友可能知道,2019年10月5日,NBA休斯敦火箭总经理莫雷在Twitter上发布了一张无知的港图片,引发了全体中国人民的强烈抗议。 不满,有一段时间,公众舆论震惊

关心篮球或喜欢访问社交网站的朋友可能知道,2019年10月5日,NBA休斯敦火箭总经理莫雷在Twitter上发布了一张无知的港图片,引发了全体中国人民的强烈抗议。 
不满,有一段时间,公众舆论震惊了。从那时起,NBA总裁肖华就此回应说,他支持莫雷,并再次引爆了公众舆论。自事件发展以来已经一周了。主要的矛盾制造者,当事方,莫雷和笑话都没有道歉和re悔,甚至把矛盾转移到了两家之间的各个群体中。 他的态度傲慢自大,内心险恶,他公开干涉他的内政和主权。这次我们不会愿意放弃。
 
这些天,Twitter,微博,虎扑,智虎等主要网站都充满了战争。网友们都在关注这一事件的新闻,他们已经竭尽全力发表了很多评论。 肮脏的语言是难看的。 
在这里,我还请同胞不要以自己的见解来责备同胞,也不要开始瓦解自己。只要我们把握主要矛盾,莫雷就必须站起来道歉,必须辞去火箭总经理的职务。校花还必须站起来道歉并解雇莫雷。 
这是道歉的最基本的诚意,可以挽救咱们球迷的心。 
当然,时间最终会给我们答案。在我们等待答案的日子里,世界各地越来越多的人会谈论它。当然,我们不会闲着,我们每天都会与所有主要的社交媒体软件打招呼。 
 Morey表达我们的言论自由。

 

 这是湖人球员詹姆斯今天接受媒体采访后,连发两条推特谈论莫雷事件,目前下面评论都是喷他的,可以说里外不是人了。不过这不是本篇的重点,作为技术公众号,我们从技术的角度来思考一下,这件事发生以来,舆论是怎样发酵的?是通过什么样的方式呢?来进入我们今天的主题,Java设计模式之——模板方法模式。

 什么是模板方法模式

 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.

Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's  structure.

 模板方法模式(Template Method Pattern):定义一个操作中的算法的框架,而将一些步骤延迟到子类中。模板方法允许子类在不改变算法结构的情况下重新定义算法的某些步骤。模板方法模式属于行为型模式,主要使用Java的继承机制来实现。

 模板方法,顾名思义就是一个模板,按照模板做事,模板方法里封装了方法的执行步骤,调用方只需要通过调用模板就能按照正确的顺序把事情做好。

 模板方法模式的两个角色

 AbstractClass(抽象类):定义了一系列基本操作(PrimitiveOperations),这些基本操作(方法)可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中定义了一个模板方法(Template Method),也就是定义了一个算法的框架,并定义组合好了这些操作的执行顺序。

  • ConcreteClass(具体子类):抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

模板方法模式UML图

 

  模板方法模式代码演示

 有小伙伴要问了,模板方法模式和莫雷事件有什么关系吗?他们二者之间本身并没有任何关联,我是在观察大家在面对这件事的态度,以及我们表达我们观点所采用的方式。再抽象一下,我们每个人对这件事的行为是不是可以简单的抽象成,打开社交软件,发表观点和意见、关闭社交软件。这是什么?运用到项目上来看,这不就是一个模板方法吗?大家都是按照这个模板在表达观点,不同的是有的人用的微博,有的人用的虎扑,有的用的推特,有的支持莫雷,有的骂莫雷等等。我们来看一下代码实现。

 1、编写抽象模板类

package com.mazhichu.designpatterns.templatemethod;
/** * <p class="detail"> * 功能: 抽象模板类 * </p> * * @author Moore * @ClassName Comment. * @Version V1.0. * @date 2019.10.16 11:53:02 */public abstract class Comment {
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    protected abstract void openSocialSoftware();
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    protected abstract void comment();
    /**     * <p class="detail">     * 功能: 具体方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    protected void closeSocialSoftware(){        System.out.println("关闭社交软件");    }
    /**     * <p class="detail">     * 功能: 模板方法,模板方法,为了防止恶意的操作,一般模板方法都加上final关键字,子类不可实现     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    public final void temtemplateMethod(){        openSocialSoftware();        comment();        closeSocialSoftware();    }

}

 2、编写具体类

package com.mazhichu.designpatterns.templatemethod;
/** * <p class="detail"> * 功能: 具体类 * </p> * * @author Moore * @ClassName Zhang san. * @Version V1.0. * @date 2019.10.16 14:00:09 */public class ZhangSan extends Comment {    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void openSocialSoftware() {        System.out.println("打开微博!");    }
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void comment() {        System.out.println("评论是:莫雷必须道歉,肖华必须道歉!解雇莫雷!");    }}
package com.mazhichu.designpatterns.templatemethod;
/** * <p class="detail"> * 功能: 具体类 * </p> * * @author Moore * @ClassName Li si. * @Version V1.0. * @date 2019.10.16 13:59:56 */public class LiSi extends Comment {    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void openSocialSoftware() {        System.out.println("打开虎扑");    }
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void comment() {        System.out.println("评论是:莫雷是傻X,WQNMLGB");    }}
package com.mazhichu.designpatterns.templatemethod;
/** * <p class="detail"> * 功能: 具体类 * </p> * * @author Moore * @ClassName James. * @Version V1.0. * @date 2019.10.16 13:59:01 */public class James extends Comment {    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void openSocialSoftware() {        System.out.println("打开推特");    }
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void comment() {        System.out.println("评论是:肖华应该惩罚莫雷!");    }}

 3、客户端调用

package com.mazhichu.designpatterns.templatemethod;
public class Client {
    public static void main(String[] args) {        Comment zhangSan = new ZhangSan();        zhangSan.temtemplateMethod();
        System.out.println("-----------------
");
        Comment lisi = new LiSi();        lisi.temtemplateMethod();
        System.out.println("-----------------
");
        Comment james = new James();        james.temtemplateMethod();
    }}

 查看运行结果:

 上面就是模板方法模式,可能是最常见也是最简单的设计模式了,父类(抽象类)定义算法和模板方法,模板方法约定好算法执行顺序,子类只需要实现父类的抽象算法,就能按照模板方法既定的顺序执行得到不同的结果,这样做大大简化了子类的复杂度。

 钩子方法

 为什么把这个单独拿出来说,是因为在模板方法中有些方法是否执行是可选的,也就是不是所有模板中的算法都需要被执行,可以由子类来决定,这就是我们要说的“钩子方法”。

钩子方法是一种被声明在抽象类中的方法,一般是空实现或者有默认值,子类可以实现覆盖该钩子,来决定算法步骤的某一步骤是否要执行,这是一种反向控制。

我们来改造一下抽象类,加入钩子方法。

 1、重新抽象类,加入钩子方法

package com.mazhichu.designpatterns.templatemethod;
/** * <p class="detail"> * 功能: 抽象模板类 * </p> * * @author Moore * @ClassName Comment. * @Version V1.0. * @date 2019.10.16 11:53:02 */public abstract class Comment {
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    protected abstract void openSocialSoftware();
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    protected abstract void comment();
    /**     * <p class="detail">     * 功能: 具体方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    protected void closeSocialSoftware(){        System.out.println("关闭社交软件");    }
    /**     * <p class="detail">     * 功能: 模板方法,为了防止恶意的操作,一般模板方法都加上final关键字,子类不可实现     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    public final void temtemplateMethod(){        openSocialSoftware();
        if(isLogin()){            comment();        }else {            System.out.println("您未登录,不可以发表评论哦,只能看别人骂莫雷");        }
        closeSocialSoftware();    }
    /**     * 钩子方法:可以是抽象方法,空实现或默认实现,子类可以覆写来决定模板方法是否执行某些算法     * @return     */    protected boolean isLogin(){        System.out.println("登录后才可以评论---");        return true;    }}

 2、编写一个覆盖钩子方法的子类

package com.mazhichu.designpatterns.templatemethod;
public class LaoBao extends Comment {    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void openSocialSoftware() {        System.out.println("打开知乎");    }
    /**     * <p class="detail">     * 功能: 基本抽象方法     * </p>     *     * @author Moore     * @date 2019.10.16 11:53:02     */    @Override    protected void comment() {        System.out.println("我不但想骂莫雷肖华,还想问候川普");    }
    @Override    protected boolean isLogin() {        return false;    }}

 3、客户端调用

package com.mazhichu.designpatterns.templatemethod;
public class Client {
    public static void main(String[] args) {        Comment zhangSan = new ZhangSan();        zhangSan.temtemplateMethod();
        System.out.println("-----------------
");
        Comment lisi = new LiSi();        lisi.temtemplateMethod();
        System.out.println("-----------------
");
        Comment james = new James();        james.temtemplateMethod();
        System.out.println("-----------------
");
        Comment laobao = new LaoBao();        laobao.temtemplateMethod();    }}

 4、查看运行结果:

通过结果可以得出,加入钩子方法后,可以反向控制父类中的模板方法中某些算法是否要被执行,这样也增加了模板方法的灵活性。

 总结

 模板方法模式优点

  • 良好的封装性和扩展性。把公共行为封装在父类,通过子类实现具体行为逻辑,增加功能由子类实现基本方法扩展,复合单一职责原则和开闭原则。

  • 提高代码的复用性,模板方法模式就是一种代码复用技术,在类库设计中尤为重要。

  • 反向控制,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。

 模板方法模式缺点

  • 模板方法使用继承方式复用代码,如果要在抽象类里增加一个抽象方法,则每一个子类都要修改代码。

  • 每一个不同的实现都需要通过一个子类来实现,导致类的个数增加,系统变得庞大。

 模板方法应用场景

  • 多个子类中有公共的方法,并且逻辑相同,可以集中到公共父类中防止代码重复。

  • 一些重要复杂的算法,可以把算法中不变的部分设计成模板方法,可变的部分由子类实现。

  • 需要通过子类来控制父类中某个算法是否执行,通过钩子方法实现反向控制。

 知识点,用笔记下来

 为防止恶意操作,一般都在模板方法上加上 final 关键词,防止子类改变模板方法中的算法执行顺序。

  • 策略模式和模板方法都是用于封装算法,前者是利用组合和委托模型,而后者则是继承。

 番外 

上面就是关于模板方法模式的讲解,其实很简单,就是我们常用的封装和继承。这儿想说的是,其实设计模式没有那么枯燥与复杂,平常多留意我们生活中的日常琐事,多思考,知识都来源于生活的观察与总结,设计模式也在我们生活中的点点滴滴里。最后,香港是中国的,任何国家、任何组织、任何势力、任何个人都无权干预我国内政,无权干涉我们领土主权的完整。希望香港早日安宁下来,再谈其他事。

维护站点不易,如果您觉得文章对你有帮助。

赞赏激励下吧,谢谢支持! ~(@^_^@)~!

赞赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,一分一毛不嫌少

打开支付宝扫一扫,即可进行扫码打赏哦

学的不仅是技术,更是梦想!!!



本站系原创文章其中有部分转载,转载目的在于传递更多信息, 并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本网联系, 我们将在第一时间删除内容![声明]本站文章版权归原作者所有 内容为作者个人观点 本站只提供参考并不构成任何投资及应用建议。本站拥有对此声明的最终解释权。
 

Tags:java、NBA、莫雷、

顶一下
(5)
100%
踩一下
(0)
0%

发表评论

评论列表(条)