Modo de plantilla: amplíe su canalización de forma elegante y flexible

El método de plantilla, como patrón de comportamiento , define el esqueleto del algoritmo de una operación en una clase o interfaz abstracta, y retrasa la ejecución específica de algunos pasos a la subclase, por lo que la ejecución del método de la clase padre puede ser diferente. Por lo tanto, se logran los propósitos de diseño de reutilización de código, buena escalabilidad y alta flexibilidad.

Cuándo usar

Cuando se usa el método de plantilla, es principalmente el caso donde se usan más los mismos métodos y similares. Con el método de plantilla, estos métodos similares se pueden extraer y se puede formular una plantilla relativamente universal, lo que reduce la escritura repetitiva de código y mejora la tasa de reutilización de código. Los escenarios de uso abstracto y la lógica de implementación se muestran en la siguiente figura.

imagen-20220327125629386.png

definición básica

Antes de comprender cómo escribir métodos de plantilla, es necesario comprender algunos términos clave y términos relacionados con los métodos de plantilla.

método básico:

Los métodos básicos se pueden dividir en las siguientes tres categorías:

1. Método concreto

El método específico se refiere al método implementado por la clase/interfaz padre, y la subclase no puede cambiar el método.

2. Método abstracto

El método abstracto significa que la clase/interfaz principal no implementa los pasos específicos, pero los pasos de operación específicos se posponen a la implementación de la subclase, a fin de lograr diferentes operaciones para diferentes situaciones.

3. Método de gancho

Un método gancho es declarado e implementado por una clase abstracta y las subclases lo amplían. Es un método que las subclases pueden implementar o no implementar de manera selectiva . Por lo general, una clase abstracta recibe una implementación vacía como la implementación predeterminada del método.

Tal implementación predeterminada se denomina método de gancho predeterminado . Este método de gancho vacío también se llama "Gancho de no hacer nada". El método de enganche predeterminado también se utiliza en el modo de adaptación predeterminado. El patrón de adaptación predeterminado es que una clase proporciona una implementación vacía predeterminada de la interfaz, de modo que las subclases no tienen que proporcionar implementaciones de todos los métodos, porque normalmente una clase concreta no necesita todos los métodos. Esta idea coincide con el método de gancho por defecto.

​ 钩子方法常见的用途为,将两个存在不同调用关系的pipeLine流程,通过钩子方法联系到同一个模版中,从而屏蔽不同内容的差异性。但是,需要注意的一点是,**钩子方法的名字应当以do开始,这是熟悉设计模式的Java开发人员的标准做法。**如doScan、doGet等。

模版方法:

​ 模版方法是模版模式的核心点,其是定义在抽象类中的,是把基本操作方法组合在一起形成总的算法或行为的方法。一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。原则上,子类不可以、也不应该对模版方法进行覆盖或者重写

上述定义中各类方法的对应模块大致如下图所示:

imagen-20220327133826087.png

代码实践

模版方法的实现,在java中有两种方式,一种是基于抽象类的实现方式,另外一种则是基于接口的实现方式

这里我们以抽象类的实现方法为例子介绍相应的模版方法的实现。

public abstract class Template {

    public void concreteMethod() {
        System.out.println("concreteMethod:");
    }

    public abstract void abstractMethod();

    public void hookMethod(){
        System.out.println("hookMethod:");
        System.out.println("实现默认hookMethod!");
    }


    public final void execute() {
        concreteMethod();

        abstractMethod();

        hookMethod();
    }
}
复制代码

首先,定义出我们的模版接口,其中包含三个方法concreteMethod、abstractMethod、hookMethod。就分别对应于我们上述提到的具体方法、抽象方法及钩子方法

然后在execute()方法内,定义好三个方法的基本执行方法,同时采用final修饰符,使得子类无法修改execute方法中的执行顺序。

然后在我们的子类HerFuction中,首先必须要对抽象方法进行相应的实现。这里我们简单的输出类名。

而在钩子方法hookMethod中,我们则对原方法进行增强,多输出一句话:“我还要执行自己的hookMethod方法!”。

public class HerFunction implements Template {

    @Override
    public void abstractMethod() {
        System.out.println("HerFunciton !");
    }

    @Override
    public void hookMethod() {
        Template.super.hookMethod();
        System.out.println("我还要执行自己的hookMethod方法!");
    }
}
复制代码

De manera similar, en la segunda subclase MyFunction, también debemos implementar el método de clase abstracta correspondiente. Pero para el método de enganche, se puede usar el método de la clase abstracta predeterminada.

public class MyFunction extends Template {

    @Override
    public void abstractMethod() {
        System.out.println("My Function!");
    }
}
复制代码

Finalmente, cree objetos correspondientes a MyFunction y HerFunction respectivamente en el método de inicio y llame al método de ejecución de la clase principal.

    public static void main(String[] args) {
        Template myFunction = new MyFunction();
        myFunction.execute();
        System.out.println("================我是分割线=========================");
        Template herFunction = new HerFunction();
        herFunction.execute();
    }
复制代码

El resultado final es el siguiente:

imagen-20220327145635211.png

Se puede ver que las subclases han reutilizado con éxito el método concreteMethod, mientras que para abstractMethod se han implementado diferentes lógicas según las diferentes subclases, lo que refleja las diferencias. Al mismo tiempo, la implementación predeterminada y la implementación de la subclase del método gancho también reflejan la flexibilidad de la plantilla.

Análisis de ventajas y desventajas.

ventaja:

1. El uso del método de plantilla para colocar el código de la misma lógica de procesamiento en la clase principal abstracta puede mejorar la reutilización del código.

2. Coloque los códigos de procesamiento del mismo significado comercial en diferentes subclases y agregue nuevos comportamientos al extender las subclases, mejorando así la capacidad de expansión del código.

3. Escriba el comportamiento sin cambios en la clase principal, elimine el código duplicado de la subclase y proporcione una buena plataforma de reutilización de código, que se ajuste al principio abierto-cerrado.

defecto:

1. La implementación del método de plantilla depende de la construcción de subclases, por lo que la cantidad de clases aumentará significativamente, aumentando la complejidad de la clase.

2. En el caso de las clases abstractas, la relación de herencia en sí misma tiene ciertas deficiencias.Si la clase principal agrega un nuevo método abstracto, todas las subclases deben implementar el método abstracto. El lenguaje JAVA puede usar la palabra clave interfaz + predeterminada para evitar esta modificación hasta cierto punto. (Pero el efecto secundario es que no puede usar final para limitar el método)

referencias

Modo plantilla (Template) de "JAVA Design Patterns"

Modo de plantilla

Explicar las razones esenciales para introducir la palabra clave predeterminada en la interfaz Java8

Ventajas y desventajas del patrón de plantilla.

Supongo que te gusta

Origin juejin.im/post/7079680230104760327
Recomendado
Clasificación