Mode modèle : étendez votre pipeline avec élégance et flexibilité

La méthode template, en tant que pattern comportemental , définit le squelette d'algorithme d'une opération dans une classe abstraite ou une interface, et retarde l'exécution spécifique de certaines étapes à la sous-classe, de sorte que l'exécution de la méthode de la classe parente peut être différente du résultat. Ainsi, les objectifs de conception de la réutilisation du code, une bonne évolutivité et une grande flexibilité sont atteints.

Quand utiliser

Lorsque la méthode du modèle est utilisée, c'est principalement le cas où les mêmes méthodes et des méthodes similaires sont davantage utilisées. En utilisant la méthode de modèle, ces méthodes similaires peuvent être extraites et un modèle relativement universel peut être formulé, réduisant ainsi l'écriture répétitive de code et améliorant le taux de réutilisation de code. Les scénarios d'utilisation abstraits et la logique d'implémentation sont illustrés dans la figure suivante.

image-20220327125629386.png

définition de base

Avant de comprendre comment écrire des méthodes de modèle, il est nécessaire de comprendre certains termes clés et termes liés aux méthodes de modèle.

méthode de base :

Les méthodes de base peuvent être divisées en trois catégories :

1. Méthode concrète

La méthode spécifique fait référence à la méthode implémentée par la classe/interface parente, et la sous-classe ne peut pas modifier la méthode.

2. Méthode abstraite

La méthode abstraite signifie que les étapes spécifiques ne sont pas implémentées par la classe/interface parente, mais que les étapes d'opération spécifiques sont reportées à l'implémentation de la sous-classe, de manière à réaliser différentes opérations pour différentes situations.

3. Méthode du crochet

Une méthode hook est déclarée et implémentée par une classe abstraite, et des sous-classes l'étendent. C'est une méthode que les sous-classes peuvent implémenter ou non de manière sélective . Habituellement, une classe abstraite reçoit une implémentation vide comme implémentation par défaut de la méthode.

Une telle implémentation par défaut est appelée une méthode de hook par défaut . Cette méthode de hook vide est également appelée "Do Nothing Hook". La méthode de hook par défaut est également utilisée dans le mode d'adaptation par défaut. Le modèle d'adaptation par défaut est qu'une classe fournit une implémentation vide par défaut de l'interface, de sorte que les sous-classes n'ont pas à fournir des implémentations de toutes les méthodes, car généralement une classe concrète n'a pas besoin de toutes les méthodes. Cette idée coïncide avec la méthode de hook par défaut.

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

模版方法:

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

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

image-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 même, dans la deuxième sous-classe MyFunction, nous devons également implémenter la méthode de classe abstraite correspondante. Mais pour la méthode hook, la méthode de la classe abstraite par défaut peut être utilisée.

public class MyFunction extends Template {

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

Enfin, créez des objets correspondant respectivement à MyFunction et HerFunction dans la méthode de démarrage, et appelez la méthode execute de la classe parent.

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

Le résultat final est le suivant :

image-20220327145635211.png

On peut voir que les sous-classes ont réutilisé avec succès la méthode concreteMethod, tandis que pour abstractMethod, différentes logiques ont été implémentées selon différentes sous-classes, reflétant les différences. Dans le même temps, l'implémentation par défaut et l'implémentation de la sous-classe de la méthode hook reflètent également la flexibilité du modèle.

Analyse des avantages et des inconvénients

avantage:

1. L'utilisation de la méthode de modèle pour placer le code de la même logique de traitement dans la classe parente abstraite peut améliorer la réutilisabilité du code.

2. Placez les codes de traitement ayant la même signification métier dans différentes sous-classes et ajoutez de nouveaux comportements en étendant les sous-classes, améliorant ainsi l'évolutivité du code.

3. Écrivez le comportement inchangé sur la classe parent, supprimez le code en double de la sous-classe et fournissez une bonne plate-forme de réutilisation de code, conforme au principe ouvert-fermé.

défaut:

1. L'implémentation de la méthode de modèle dépend de la construction de sous-classes, de sorte que le nombre de classes augmentera considérablement, augmentant la complexité de la classe.

2. Dans le cas des classes abstraites, la relation d'héritage elle-même présente certaines lacunes : si la classe mère ajoute une nouvelle méthode abstraite, toutes les sous-classes doivent implémenter la méthode abstraite. Le langage JAVA peut utiliser le mot clé interface + default pour éviter dans une certaine mesure cette modification. (Mais l'effet secondaire est que vous ne pouvez pas utiliser final pour limiter la méthode)

les références

Mode modèle (Template) de "JAVA Design Patterns"

Mode modèle

Expliquer les raisons essentielles de l'introduction du mot-clé par défaut dans l'interface Java8

Avantages et inconvénients du modèle de modèle

Je suppose que tu aimes

Origine juejin.im/post/7079680230104760327
conseillé
Classement