Método de plantilla (patrón de diseño)

método de plantilla
método de plantilla
Tipo de conductual
Estructura
Descrito en Patrones de diseño

Un  método de plantilla es un patrón de diseño de comportamiento que define la base de un algoritmo y permite a los sucesores redefinir algunos pasos del algoritmo sin cambiar su estructura como un todo.

Aplicabilidad

Miembros

Clase abstracta (clase abstracta): define las operaciones abstractas que se reemplazan en los herederos para implementar los pasos del algoritmo; implementa un método de plantilla que define el esqueleto del algoritmo. El método de plantilla llama a las operaciones reemplazadas y otras definidas en la clase Abstract.

Clase concreta (clase concreta): implementa las operaciones reemplazadas de la manera necesaria para esta implementación.

La clase Concrete asume que los pasos invariantes del algoritmo se realizarán en AbstractClass .

Ejemplos

En los ejemplos, el método de plantilla se implementa para juegos.

C++11

Texto fuente en C++11 /** * Una clase abstracta que es común a varios juegos en los que * los jugadores juegan contra otros, pero solo uno está * jugando en un momento dado. */ clase GameObject { protegido : int CuentaJugadores ; virtual bool EndOfGame () = 0 ; vacío virtual InitializeGame () = 0 ; virtual void MakePlay ( jugador int ) = 0 ; vacío virtual PrintWinner () = 0 ; público : /* Un método de plantilla: */ void PlayOneGame ( int playersCount ) { PlayersCount = playersCount ; InicializarJuego (); int j = 0 ; while ( ! Fin del juego ()) { Hacer Jugar ( j ); j = ( j + 1 ) % jugadoresCount ; } ganador de impresión (); } }; clase Monopoly : GameObject público { protegido : /* Implementación de métodos concretos necesarios */ void InitializeGame () anular { // Inicializar dinero } invalidar la anulación de MakePlay ( jugador int ) { // Procesar un turno de jugador } anular bool EndOfGame () { devolver verdadero ; } anular PrintWinner () anular { // Mostrar quién ganó } }; Ajedrez de clase : GameObject público { protegido : /* Implementación de métodos concretos necesarios */ void InitializeGame () anular { // Poner las piezas en el tablero } invalidar la anulación de MakePlay ( jugador int ) { // Procesar un turno para el jugador } anular bool EndOfGame () { // Devuelve true si se ha llegado a Jaque mate o Stalemate return true ; } anular PrintWinner () anular { // Mostrar el jugador ganador } }; int principal () { GameObject * juego = nuevo Monopoly (); juego -> PlayOneGame ( 2 ); devolver 0 ; }

Java

Fuente Java paquete com.designpatterns.templatemethod ; /* Códigos de variación del juego. * * Archivo GameCode.java * */ public enum GameCode { AJEDREZ , MONOPOLIO } /* Una clase abstracta cuya implementación de métodos abstractos será específica para cada tipo de juego. * * Archivo Juego.java * */ Juego de clase pública abstracta { cantidad de jugadores privados int ; Vacío abstracto protegido initializeGame (); juego vacío abstracto protegido (); endGame vacío abstracto protegido (); printWinner abstracto vacío protegido (); playOneGame public final void ( int cantidad de jugadores ){ set Cantidad de jugadores ( cantidad de jugadores ); inicializarJuego (); jugarJuego (); final del juego (); imprimirGanador (); } public void setPlayersAmount ( int playersAmount ){ esto . cantidad de jugadores = cantidad de jugadores ; } } paquete com.designpatterns.templatemethod ; /* Juego "Ajedrez". Específicamente para ajedrez, implementa los métodos de la clase Game. * * Archivo Ajedrez.java * */ El ajedrez de clase pública extiende el juego { @Override protected void initializeGame () { // acciones de inicialización específicas del ajedrez } @Override protected void playGame () { // acciones de juego específicas de ajedrez } @Override protected void endGame () { // Acciones específicas de ajedrez para finalizar un juego } @Override protected void printWinner () { // acciones específicas de ajedrez para imprimir el ganador } } paquete com.designpatterns.templatemethod ; /* Juego de monopolio. Específico de Monopoly, implementa los métodos de la clase Game. * * Archivo Monopoly.java * */ El monopolio de clase pública extiende el juego { @Override protected void initializeGame () { // acciones de inicialización específicas del monopolio } @Override protected void playGame () { // acciones de juego específicas del monopolio } @Override protected void endGame () { // acciones específicas de monopolio para finalizar un juego } @Override protected void printWinner () { // acciones específicas del monopolio para imprimir el ganador } } paquete com.designpatterns.templatemethod ; /* Una clase que muestra cómo funciona el patrón de diseño del método de plantilla. * * Archivo GamesManager.java * */ administrador de juegos de clase pública { public static void main ( String [] args ){ código de juego final código de juego = código de juego . AJEDREZ ; juego juego _ cambiar ( código de juego ) { caso AJEDREZ : juego = nuevo Ajedrez (); romper ; caso MONOPOLY : juego = nuevo Monopoly (); romper ; predeterminado : lanza una nueva IllegalStateException (); } juego _ jugar un juego ( 2 ); } }

C#

Texto fuente en C# /** * Una clase abstracta que es común a varios juegos en los que * los jugadores juegan contra otros, pero solo uno está * jugando en un momento dado. */ namespace Design_Patterns { class TemplateMethodPattern { clase abstracta interna GameObject { protected int PlayersCount ; resumen protegido bool EndOfGame (); resumen vacío protegido InitializeGame (); resumen vacío protegido MakePlay ( jugador int ); abstracto vacío protegido PrintWinner (); /* Un método de plantilla: */ public void PlayOneGame ( int playersCount ) { PlayersCount = playersCount ; InicializarJuego (); var j = 0 ; while (! EndOfGame ()) { MakePlay ( j ); j = ( j + 1 ) % jugadoresCount ; } ganador de impresión (); } } //Ahora podemos extender esta clase para implementar juegos reales: public class Monopoly : GameObject { /* Implementación de métodos concretos necesarios */ protected override void InitializeGame () { // Inicializa el dinero } protected override void MakePlay ( int player ) { // Procesar un turno de jugador } protected override bool EndOfGame () { return true ; } protected override void PrintWinner () { // Mostrar quién ganó } /* Declaraciones específicas para el juego Monopoly. */ // ... } Ajedrez de clase pública : GameObject { /* Implementación de métodos concretos necesarios */ protected override void InitializeGame () { // Poner las piezas en el tablero } protected override void MakePlay ( int player ) { // Procesar un turno para el jugador } protected override bool EndOfGame () { return true ; // Devuelve verdadero si se ha llegado a Jaque mate o Stalemate } protected override void PrintWinner () { // Mostrar el jugador ganador } /* Declaraciones específicas para el juego de ajedrez. */ // ... } Prueba de vacío estático público () { GameObject juego = nuevo Monopoly (); juego _ Juego PlayOne ( 2 ); } } }

Pitón

Código fuente en Python de abc import ABCMeta , método abstracto Unidad de clase ( metaclase = ABCMeta ): """ Una unidad abstracta. Los atributos de clase que comienzan con un guión bajo en python están protegidos """ def __init__ ( self , velocidad : int ) -> Ninguno : """ Constructor. :param velocidad: unidad de velocidad " "" self ._speed = velocidad def hit_and_run ( self ) -> Ninguno : """ Método de plantilla """ self . _mover ( 'adelante' ) self . _stop () auto . _ataque () auto . _mover ( 'hacia atrás' ) @abstractmethod def _attack ( self ) -> Ninguno : pasar @abstractmethod def _stop ( auto ) -> Ninguno : pasar def _move ( self , dirección : str ) -> Ninguno : """ Movimiento: todas las unidades tienen el mismo, no incluido en la plantilla :param dirección: dirección del movimiento """ self ._output ( ' mueve {} a velocidad {} ' . format ( dirección , self . _velocidad )) def _output ( self , mensaje : str ) -> Ninguno : """ Método auxiliar de salida de mensajes, no incluido en la plantilla :param mensaje: mensaje para imprimir """ print ( 'Escuadrón de tipo {} {} ' . format ( self . __class__ . __name__ , message )) clase Arqueros ( Unidad ): """ Arqueros """ def _attack ( self ) -> Ninguno : self . _output ( 'bombardea al enemigo' ) def _stop ( self ) -> Ninguno : self . _output ( 'se detiene a 100 pies del enemigo' ) clase Soldados de caballería ( Unidad ): """ Soldados de caballería """ def _attack ( self ) -> Ninguno : self . _output ( 'Se estrella contra la formación enemiga a todo galope' ) def _stop ( self ) -> Ninguno : self . _output ( 'vuela hacia adelante sin detenerse' ) if __name__ == '__main__' : print ( 'OUTPUT:' ) arqueros = arqueros ( 4 ) arqueros . hit_and_run () jinetes = jinetes ( 8 ) jinetes . golpea_y_corre () ''' SALIDA: La unidad de tipo Arquero avanza a una velocidad de 4 La unidad de tipo Arquero se detiene a 100 pasos de un enemigo La unidad de tipo Arquero dispara a un enemigo La unidad de tipo Arquero retrocede a una velocidad de 4 La unidad de tipo Caballería se mueve hacia delante a una velocidad de 8 unidades de tipo Caballería vuela hacia adelante sin detenerse unidad de tipo caballería a todo galope choca contra la formación enemiga unidad de tipo caballería se mueve hacia atrás a una velocidad de 8 '''

Literatura

  • E. Gamma, R. Helm, R. Johnson, J. Vlissides . Técnicas de diseño orientado a objetos. Patrones de Diseño = Patrones de Diseño: Elementos de Software Reutilizable Orientado a Objetos. - San Petersburgo. : "Pedro" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . (también ISBN 5-272-00355-1 )

Enlaces