Introducción del método de plantilla de patrones de diseño a la situación real

Método de plantilla

¿Qué es el método de plantilla?

La idea de diseño del método Template

En pocas palabras, es para evitar que en el proceso de implementación de un algoritmo en múltiples subclases, los desarrolladores de aplicaciones escriban el proceso de algoritmo incorrecto, lo que conduce a resultados incorrectos. Dejamos que los desarrolladores de la biblioteca de clases escriban un esqueleto de algoritmo fijo (¡por lo que este modo solo se puede adaptar a los escenarios de aplicación donde el esqueleto del algoritmo está básicamente determinado!). Deje que algunos de los algoritmos y pasos comunes a todas las clases se implementen en la biblioteca de clases, y luego deje que diferentes desarrolladores de aplicaciones escriban algunos de los pasos adecuados para la escena actual, y luego llame al método esqueleto de la clase principal para implementar el algoritmo.

¿Qué tipos de métodos hay en el patrón de diseño del método de plantilla?

Primero: un método fijo implementado por la biblioteca de clases y no puede ser modificado por el desarrollador de la aplicación

Por ejemplo, en los siguientes procedimientos comerciales bancarios reales de combate 1, se toma el número y el negocio se termina para dar una evaluación. Estos dos pasos son aplicaciones diferentes que no necesitan ser administradas, por lo que se configuran como finales (en la programación Java, es final, si es Para la programación en C ++, escriba la realización de la función como const!). Estos programas a menudo son códigos que no tienen nada que ver con ningún desarrollador de aplicaciones. Se configuran como finales para evitar modificaciones inadvertidas por parte del desarrollador de aplicaciones, lo que lleva a resultados incorrectos del algoritmo.

Segundo: es implementado por la biblioteca de clases, pero el desarrollador de la aplicación puede considerar modificaciones o no de acuerdo con la situación real.

Por ejemplo, el programa de análisis de datos del combate real 2 a continuación, los datos en los escenarios de aplicación de algunas aplicaciones (subcategorías) deben procesarse antes de ser analizados. Sin embargo, algunos datos se pueden analizar directamente. Por ejemplo, los datos de Excel a menudo se pueden procesar directamente después de la descarga, pero algunos datos de gráficos de barras deben procesarse después del procesamiento secundario. Entonces podemos configurar un método de gancho de "función de gancho", este método generalmente devuelve un valor booleano (booleano / bool). Si es necesario manejar la mayoría de las situaciones, devolveremos falso a este método de enlace de forma predeterminada para evitar que algunos desarrolladores de aplicaciones se olviden de manejarlo y entren en el proceso de análisis de datos. Si los datos actuales no requieren procesamiento secundario, la subclase extendida debería anular este método y devolver verdadero.

Tercero: el método abstracto que implementa el desarrollador de la aplicación, independientemente de la clase abstracta

En Java, los métodos abstractos están representados por la palabra clave abstract y las clases con métodos etiquetados como abstractos se denominan clases abstractas. Si está en C ++, es para establecer una función virtual pura, y la clase con función virtual pura es una clase abstracta. No podemos implementar este método, simplemente defínalo en la clase principal, y luego el compilador obligará al desarrollador de la aplicación a implementar la clase abstracta de acuerdo con su situación real. ¡Juega el efecto del polimorfismo en tiempo de ejecución!

Beneficios de usar el método de plantilla

¡Dejemos que el algoritmo sea fijo para lograr el efecto de una clase padre que llama a subclases, de acuerdo con el "principio de apertura y cierre"!
¡Utilice también la herencia y el polimorfismo para lograr el efecto de reutilización del código del esqueleto del algoritmo!

Práctica relacionada con el método de plantilla 1: Procedimientos de procesamiento comercial bancario

Análisis de diseño:

En el proceso de algoritmo (esqueleto) del negocio de manejo bancario, existen los siguientes pasos:
① Obtener el número
② Manejar el negocio
③ Después del negocio, dar la evaluación del negocio

Algunos de los procesos (métodos) son estáticos, es decir, los dos pasos de tomar un número y terminar el negocio. Pero el proceso de manejo de negocios es dinámico: ¡diferentes roles de usuario quieren manejar diferentes negocios! Por lo tanto, solo podemos abstraer este proceso dinámico (método) y un esqueleto de algoritmo fijo. Deje que las diferentes clases de roles que necesitan manejar el negocio hereden esta clase abstracta y luego reescriba el negocio que necesita manejarse en las subclases. Una vez finalizada la reescritura, llame a todo el proceso del esqueleto del algoritmo () en la clase principal que llama. Según el polimorfismo, se obtendrán diferentes resultados en el mismo esqueleto de algoritmo de acuerdo con diferentes subcategorías y diferentes procedimientos comerciales implementados.

Mi clase principal abstracta: BankTranscation


/**
* 这个抽象类作为模板方法的父类,完成银行业务
* @author 不会编程的小良
* @version 1.0
* */
abstract class BaseBankTranscation {
    
    

    static int ServerId = 1;

    public void takeNumber(){
    
    
        System.out.println("排队取号ing……");
    }

    /**
    * 这个抽象函数负责由子类根据具体业务完成重写
    * @author 不会编程的小良
    * @version 1.0
    * */
    public abstract void transcation();

    public void evalue(){
    
    
        System.out.println("第 " + ServerId + " 次服务结束,完成评分……");
    }

    public final void process(){
    
    
        System.out.println("开始第 " + ServerId + " 次服务!");
        takeNumber();
        transcation();
        evalue();
        ServerId++;
    }

}


Diferentes subcategorías comerciales

/**
 * 这个子类负责重写父类BaseBankTranscation的方法transcation(),完成取款业务
 * @author 不会编程的小良
 * @version 1.0
 * */
class Deposite extends BaseBankTranscation {
    
    

    @Override
    public void transcation() {
    
    
        System.out.println("我要取款……");
    }
}

/**
 * 这个子类负责重写父类BaseBankTranscation的方法transcation(),完成存款业务
 * @author 不会编程的小良
 * @version 1.0
 * */
class Withdraw extends BaseBankTranscation {
    
    

    @Override
    public void transcation() {
    
    
        System.out.println("我要存款……");
    }
}

/**
 * 这个子类负责重写父类BaseBankTranscation的方法transcation(),完成转账业务
 * @author 不会编程的小良
 * @version 1.0
 * */
class Transfer extends BaseBankTranscation {
    
    

    @Override
    public void transcation() {
    
    
        System.out.println("我要转账……");
    }
}

La clase principal llama al método de proceso de cada subclase para completar el procesamiento comercial.


/**
 * 这个主类负责完成各种银行业务的办理过程
 * @author 不会编程的小良
 * @version 1.0
 * */
public class TemplateMethod {
    
    

    public static void main(String[] args){
    
    

        int n = 3;
        BaseBankTranscation[] tran = new BaseBankTranscation[n];
        for(int i = 0;i < n;++i){
    
    
            switch (i % 3){
    
    
                case 0:
                    tran[i] = new Deposite();
                    break;
                case 1:
                    tran[i] = new Withdraw();
                    break;
                case 2:
                    tran[i] = new Transfer();
                    break;
                default:
                    break;
            }
        }
        for(BaseBankTranscation item : tran) {
    
    
            item.process();
        }

    }
}

El resultado de la ejecución es:

Inserte la descripción de la imagen aquí

Método de plantilla relacionado con el combate 2: caso de análisis y procesamiento de datos

Análisis de diseño:

Este procesamiento y análisis de datos se divide en varios pasos:

① Adquisición de datos (método abstracto para completar la solicitud)
② Conversión de datos a un modo procesable (método de gancho)
③ Análisis de datos (método abstracto para completar la solicitud)
④ Visualización de los resultados del análisis de datos (método de gancho)

Implementación de la clase padre BaseDataAnalysis

abstract class BaseDataAnalysis {
    
    

    abstract void getData();

    void connvertData(){
    
    
        System.out.println("默认的数据转换方法……");
    }

    final void analysisData(){
    
    
        System.out.println("完成数据分析工作……");
    }

    void displayData(){
    
    
        System.out.println("默认的输出方式展示……");
    }

    boolean isValid(){
    
    
        return true;
    }

    void process(){
    
    
        getData();
        if(isValid()){
    
    
            connvertData();
        }
        analysisData();
        displayData();
    }

}

Implementación de la subclase extendida SubClass

class SubClass extends BaseDataAnalysis {
    
    

    @Override
    void getData(){
    
    
        System.out.println("从JSON文件中获取数据……");
    }

    @Override
    void displayData(){
    
    
        System.out.println("以饼状图展示的方法展示……");
    }
}

Ejecución del método de prueba de la clase principal

public class TemplateMethod {
    
    
    public static void main(String[] args){
    
    
        BaseDataAnalysis sub = new SubClass();
        sub.process();
    }
}

El resultado de la ejecución es:

Inserte la descripción de la imagen aquí

Pensando y practicando

Descripción del problema:

El proceso de cálculo de intereses de un software bancario es el siguiente:

① El sistema consulta la información del usuario según la cuenta

② Juzgue el tipo de usuario según la información del usuario

③ Los diferentes tipos de usuarios utilizan diferentes métodos de cálculo de intereses (como actual, regular)

④ Muestra interés

Mi clase de interés bancario abstracto de solución:

abstract class BankInterest {
    
    

    boolean isValidUser(String username, String password){
    
    
        if("jiangzhengliang".equals(username) && "123456".equals(password)) {
    
    
            System.out.println("账户:" + username);
            System.out.println("密码:" + password);
            return true;
        }
        else {
    
    
            return false;
        }
    }

    abstract void getAccountMethod();

    final void display(){
    
    
        System.out.println("显示利息……");
    }

    void process(String name, String psswd){
    
    
        if(isValidUser(name, psswd)){
    
    
            getAccountMethod();
            display();
        }
    }

}

Subcategorías de interés fijo y actual expandidas por mi solución

class CurrentAccount extends BankInterest {
    
    

    @Override
    void getAccountMethod() {
    
    
        System.out.println("我是活期贷款……");
    }
}

class SavingAccount extends BankInterest {
    
    

    @Override
    void getAccountMethod() {
    
    
        System.out.println("我是定期贷款……");
    }
}

Mi solución-prueba la clase principal

public class TemplateMethod {
    
    
    public static void main(String[] args){
    
    
        BankInterest bank1 = new CurrentAccount();
        bank1.process("jiangzhengliang", "123456");

        BankInterest bank2 = new SavingAccount();
        bank2.process("jiangzhengliang", "123456");
    }
}

El resultado de la prueba:

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_44274276/article/details/107632746
Recomendado
Clasificación