关于java:设计模式13-模板模式怎么弄

60次阅读

共计 3311 个字符,预计需要花费 9 分钟才能阅读完成。

开局还是那种图,各位客官往下看 …

张无忌学太极拳,遗记了所有招式,打倒了 ” 玄冥二老 ”,所谓 ” 心中无招 ”。设计模式堪称招数,如果先学通了各种模式,又忘掉了所有模式而得心应手,堪称 OO 之最高境界。

模板模式是什么?

模板模式,同样是一种行为型模式,也就是对于 对象做什么或者怎么做 的设计模式。模板模式的实质须要定义操作中的算法的框架,然而有一些步骤,又不须要具体的实现,而是不同的子类各自实现。子类不能批改流程框架,然而局部的步骤能够做定制化的实现。

次要要解决一个问题:一些通用的办法,然而每一个子类却都从新写,冗余。

比如说,做菜的步骤个别是:洗锅 --> 炒菜 --> 洗碗,不同的菜,只是炒菜这一个步骤具体细节是不同的,然而其余步骤的确简直截然不同的,这样其实整体框架,以及反复的步骤,咱们能够形象到模板中,而不同的细节办法能够凋谢给每一种菜(具体实现)去定制。

又比方造房子的时候,很多中央的建造都是一样的:地基,墙壁,水管等等,然而不同的房子外面的外部的设计又有所不同。

不应用模板模式

就挑个简略的例子“炒菜”,如果不应用模板模式的话,糖醋鲤鱼:


public class SweetAndSourCarp {public void cookFood(){washPan();
        cook();
        eat();
        washDishes();
        System.out.println("");
    }

    private void washPan(){System.out.print("洗锅 -->");
    }

    private void cook(){System.out.print("煮糖醋鲤鱼 -->");
    }

    private void eat(){System.out.print("吃饭 -->");
    }

    private void washDishes(){System.out.print("洗碗 -->");
    }
}

再弄一个农家小炒肉,须要写很多雷同的办法:

public class ShreddedPorkWithVegetables {public void cookFood(){washPan();
        cook();
        eat();
        washDishes();
        System.out.println("");
    }

    private void washPan(){System.out.print("洗锅 -->");
    }

    private void cook(){System.out.print("炒农家小炒肉 -->");
    }

    private void eat(){System.out.print("吃饭 -->");
    }

    private void washDishes(){System.out.print("洗碗 -->");
    }
}

测试类如下:

public class Test {public static void main(String[] args) {SweetAndSourCarp sweetAndSourCarp = new SweetAndSourCarp();
        sweetAndSourCarp.cookFood();

        ShreddedPorkWithVegetables shreddedPorkWithVegetables = new ShreddedPorkWithVegetables();
        shreddedPorkWithVegetables.cookFood();}
}

测试后果:

洗锅 --> 煮糖醋鲤鱼 --> 吃饭 --> 洗碗 --> 
洗锅 --> 炒农家小炒肉 --> 吃饭 --> 洗碗 --> 

能够看到,整体流程是一样的,有些步骤一样,有些步骤不一样,然而不应用模板模式,须要每个类都重写一遍办法,即便是通用办法,整个流程都须要本人写一遍。

应用模板模式优化

如果应用模板模式,那么咱们会形象出一个抽象类,定义整体的流程,曾经固定的步骤,凋谢须要定制的办法,让具体的实现类依照本人的需要来定制。

定义的抽象类:

public abstract class CookFood {public final void cookFood() {washPan();
        cook();
        eat();
        washDishes();
        System.out.println("");
    }

    private final void washPan() {System.out.print("洗锅 -->");
    }

    public abstract void cook();

    private final void eat() {System.out.print("吃饭 -->");
    }

    private final void washDishes() {System.out.print("洗碗 -->");
    }
}

具体的实现类糖醋鲤鱼:

public class SweetAndSourCarp extends CookFood {
    @Override
    public void cook() {System.out.print("煮糖醋鲤鱼 -->");
    }
}

农家小炒肉:

public class ShreddedPorkWithVegetables extends CookFood {
    @Override
    public void cook() {System.out.print("炒农家小炒肉 -->");
    }
}

测试类与后面的一样,测试后果也一样,这里不再反复。

下面的办法中,其实咱们只凋谢了 cook() 办法,这就是 钩子办法

在模板办法模式的父类中,咱们能够定义一个办法,它默认不做任何事,子类能够视状况要不要笼罩它,该办法称为”钩子办法”

钩子办法是凋谢的,能够由子类随便笼罩,然而像下面的其余办法,咱们不心愿子类重写或者笼罩它,就能够用 final 关键字,避免子类重写模板办法。

模板模式的利用

其实在 JDKThread 实现中,就是应用了模板模式,咱们晓得创立线程有两个形式:

  • 创立 Thread
  • 实现 runnable 接口

咱们实现的个别是 run() 办法, 然而调用的却是 start() 办法来启动线程,这个起因就是 start() 办法外面帮咱们调用了 run() 办法,run()办法是开发的办法,咱们能够笼罩重写它。

Start0()是一个 native 办法,是由 c 语言去实现的,在调用的时候,真正调用了咱们的 run() 办法,如果须要跟踪这个办法须要到 HotSpot底层去。这里介绍的目标是让大家理解,它同样是应用了模板模式。

    private native void start0();

理解 native 关键字能够参考:http://aphysia.cn/archives/na…

模板模式的优缺点

模板模式的 长处:

  • 1、封装固定的局部,拓展须要定制批改的局部,合乎开闭准则。
  • 2、公共的代码在父类中,容易保护。
  • 3、整个流程由父类把握,调整比拟不便。

毛病:

  • 1、子类可能会很多,零碎复杂度回升。
  • 2、子类只有一小部分实现,理解全副办法则须要在父类中浏览,影响代码浏览。

总结:代码该暗藏的简单细节暗藏起来,凋谢定制化局部,优雅!

设计模式系列:

  • 设计模式【1】– 单例模式到底几种写法?
  • 设计模式【1.1】– 你想如何毁坏单例模式?
  • 设计模式【1.2】– 枚举式单例有那么好用么?
  • 设计模式【1.3】– 为什么饿汉式单例是线程平安的?
  • 设计模式【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】– 搞定组合模式
  • 设计模式【12】– 搞定最近大火的策略模式

【作者简介】
秦怀,公众号【秦怀杂货店】作者,集体网站:http://aphysia.cn,技术之路不在一时,山高水长,纵使迟缓,驰而不息。

剑指 Offer 全副题解 PDF

开源编程笔记

正文完
 0