Estrategia | |
---|---|
estrategia | |
Tipo de | conductual |
Objetivo | le permite utilizar diferentes reglas de negocio o algoritmos según el contexto. |
Se aplica en casos | cuando en el mismo lugar, dependiendo del estado actual del sistema (o su entorno), se deben usar diferentes algoritmos |
ventajas |
|
menos | creando clases adicionales |
Plantillas relacionadas | Puente , método de plantilla , adaptador |
Descrito en Patrones de diseño | Sí |
La estrategia ( eng. Strategy ) es un patrón de diseño de comportamiento diseñado para definir una familia de algoritmos , encapsular cada uno de ellos y garantizar su intercambiabilidad. Esto le permite elegir un algoritmo definiendo la clase apropiada. La plantilla de estrategia le permite cambiar el algoritmo seleccionado independientemente de los objetos de cliente que lo utilicen.
Por el tipo de cliente (o por el tipo de datos que se procesan), seleccione el algoritmo apropiado para aplicar. Si se utiliza una regla que no está sujeta a cambios, no es necesario consultar el patrón de estrategia.
Separación del procedimiento de selección de algoritmos de su implementación. Esto permite que la selección se haga en función del contexto.
La clase que usa el algoritmo ( Context) incluye una clase abstracta ( Strategy) que tiene un método abstracto que define cómo se invoca el algoritmo. Cada clase derivada implementa una versión requerida del algoritmo.
Nota: un método de llamada de algoritmo no tiene que ser abstracto si se va a implementar algún comportamiento predeterminado.
La arquitectura WDF de Microsoft se basa en este patrón. Cada objeto "controlador" y "dispositivo" tiene una parte inmutable cosida en el sistema, en la que se registra una parte mutable (estrategia) escrita en una implementación específica. La parte mutable puede estar completamente vacía, lo que dará un controlador que no hace nada, pero al mismo tiempo puede participar en PnP y administración de energía.
La biblioteca ATL contiene un conjunto de clases de modelo de subprocesamiento que son estrategias (diferentes implementaciones de Bloquear/Desbloquear, que luego son utilizadas por las clases principales del sistema). Sin embargo, estas estrategias usan polimorfismo estático a través de un parámetro de plantilla en lugar de polimorfismo dinámico a través de métodos virtuales.
ejemplo java
Ejemplo de implementación // La clase que implementa la estrategia particular debe implementar esta interfaz // La clase de contexto usa esta interfaz para invocar la estrategia particular interfaz Estrategia { int ejecutar ( int a , int b ); } // Implementar el algoritmo usando la interfaz de estrategia class ConcreteStrategyAdd implements Strategy { public int ejecutar ( int a , int b ) { System . fuera _ println ( "Llamó a ejecución de ConcreteStrategyAdd()" ); devuelve a + b ; // Haz una suma con a y b } } class ConcreteStrategySubtract implementa la estrategia { public int ejecutar ( int a , int b ) { System . fuera _ println ( "Llamó a ejecución de ConcreteStrategySubtract()" ); devuelve a - b ; // Hacer una resta con a y b } } class ConcreteStrategyMultiply implementa la estrategia { public int ejecutar ( int a , int b ) { System . fuera _ println ( "Llamado a la ejecución de ConcreteStrategyMultiply()" ); devuelve a * b ; // Haz una multiplicación con a y b } } // Clase de contexto usando la interfaz de estrategia class Context { estrategia privada estrategia ; // Constructor contexto publico () { } // Establecer nueva estrategia public void setStrategy ( Estrategia estrategia ) { this . estrategia = estrategia ; } public int executeStrategy ( int a , int b ) { estrategia de retorno . ejecutar ( a , b ); } } // Clase de aplicación de prueba StrategyExample { public static void main ( String [] args ) { Contexto contexto = nuevo contexto (); contexto _ setStrategy ( new ConcreteStrategyAdd ()); int resultadoA = contexto . ejecutarEstrategia ( 3 , 4 ); contexto _ setStrategy ( new ConcreteStrategySubtract ()); int resultadoB = contexto . ejecutarEstrategia ( 3 , 4 ); contexto _ setStrategy ( new ConcreteStrategyMultiply ()); int resultadoC = contexto . ejecutarEstrategia ( 3 , 4 ); sistema _ fuera _ println ( "Resultado A:" + resultado A ); sistema _ fuera _ println ( "Resultado B:" + resultado B ); sistema _ fuera _ println ( "Resultado C:" + resultado C ); } }Ejemplo en C++
Ejemplo de implementación #incluir <iostream> estrategia de clase { público : virtual ~ Estrategia () {} uso de vacío virtual () = 0 ; }; clase Strategy_1 : estrategia pública { público : void use (){ std :: cout << "Estrategia_1" << std :: endl ; } }; clase Strategy_2 : estrategia pública { público : void use (){ std :: cout << "Estrategia_2" << std :: endl ; } }; clase Strategy_3 : estrategia pública { público : void use (){ std :: cout << "Estrategia_3" << std :: endl ; } }; contexto de clase { protegido : estrategia * operación ; público : ~ Contexto virtual () {} useStrategy vacío virtual () = 0 ; virtual void setStrategy ( Estrategia * v ) = 0 ; }; cliente de clase : contexto público { público : estrategia de uso nulo () { operación -> uso (); } void setStrategy ( Estrategia * o ) { operación = o ; } }; int main ( int /*argc*/ , char * /*argv*/ []) { Cliente cliente personalizado ; estrategia_1 str1 ; Estrategia_2 str2 ; Estrategia_3 str3 ; cliente personalizado . establecerEstrategia ( & str1 ); cliente personalizado . usarEstrategia (); cliente personalizado . establecerEstrategia ( & str2 ); cliente personalizado . usarEstrategia (); cliente personalizado . establecerEstrategia ( & str3 ); cliente personalizado . usarEstrategia (); devolver 0 ; } Ejemplo de implementación (parámetro de plantilla) #incluir <iostream> estructura Estrategia_1 { void use (){ std :: cout << "Estrategia_1" << std :: endl ; }; }; estructura estrategia_2 { void use (){ std :: cout << "Estrategia_2" << std :: endl ; }; }; estructura Estrategia_3 { void use (){ std :: cout << "Estrategia_3" << std :: endl ; }; }; plantilla < classOperation > _ struct Cliente : operación pública { estrategia de uso nulo () { esto -> usar (); } }; int main ( int /*argc*/ , char * /*argv*/ []) { Cliente < Estrategia_1 > customClient1 ; cliente personalizado1 . usarEstrategia (); Cliente < Estrategia_2 > customClient2 ; cliente personalizado2 . usarEstrategia (); Cliente < Estrategia_3 > customClient3 ; cliente personalizado3 . usarEstrategia (); devolver 0 ; }Ejemplo en C#
Ejemplo de implementación utilizando el sistema ; namespace DesignPatterns.Behavioral.Strategy { // La clase que implementa la estrategia en particular debe heredar esta interfaz // La clase de contexto usa esta interfaz para invocar la estrategia en particular public interface IStrategy { void Algorithm (); } // Primera implementación-estrategia concreta. public class ConcreteStrategy1 : IStrategy { public void Algorithm () { Console . WriteLine ( "El algoritmo de estrategia 1 se está ejecutando" ); } } // Segunda estrategia de implementación concreta. // Puede haber tantas implementaciones como quieras. public class ConcreteStrategy2 : IStrategy { public void Algorithm () { Console . WriteLine ( "El algoritmo de estrategia 2 se está ejecutando" ); } } // Contexto que utiliza la estrategia para resolver su problema. public class Context { // La referencia a la interfaz IStrategy // le permite cambiar automáticamente entre implementaciones específicas // (en otras palabras, esta es la elección de una estrategia específica). privado IStrategy_strategy ; _ // Constructor de contexto. // Inicializa el objeto con la estrategia. Contexto público ( estrategia de IStrategy ) { _strategy = estrategia ; } // Método para establecer la estrategia. // Se usa para cambiar la estrategia en tiempo de ejecución. // En C#, también se puede implementar como una propiedad de registro. public void SetStrategy ( estrategia de IStrategy ) { _strategy = estrategia ; } // Alguna funcionalidad de contexto que elige // una estrategia y la utiliza para realizar su tarea. public void ExecuteOperation () { _strategy . algoritmo (); } } // Clase de aplicación. // Actúa como un cliente de contexto en este ejemplo. public static class Program { // <summary> // Punto de entrada del programa. // </summary> public static void Main () { // Crea un contexto e inicialízalo con la primera estrategia. Contexto context = nuevo Contexto ( new ConcreteStrategy1 ()); // Realiza una operación de contexto que usa la primera estrategia. contexto _ EjecutarOperación (); // Reemplazar la primera estrategia con la segunda en el contexto. contexto _ SetStrategy ( nueva ConcreteStrategy2 ()); // Realiza la operación de contexto, que ahora usa la segunda estrategia. contexto _ EjecutarOperación (); } } }Ejemplos en D
Ejemplo de implementación estándar de importación estudio _ interfaz IStrategy { int Action ( int a , int b ); } class TAddition : IStrategy { public int Action ( int a , int b ) { return a + b ; } } class TSubtraction : IStrategy { public int Action ( int a , int b ) { return a - b ; } } clase TContexet { privado : int a , b ; estrategia de estrategia ; public : void SetAB ( int a , int b ) { TContexet . un = un ; TContexet . b = b ; }; void SetStrategy ( estrategia IStrategy ) { TContexet . estrategia = estrategia ; } int Acción () { estrategia de retorno . Acción ( a , b ); } } void principal () { contexto TContexet = nuevo TContexet ; contexto _ Conjunto AB ( 10 , 5 ); contexto _ SetStrategy ( nuevo TAddition ); writeln ( contexto.Acción ( ) ); // quince contexto _ SetStrategy ( nuevo TSubtraction ); writeln ( contexto.Acción ( ) ); // 5 }Ejemplo en Delfos
Ejemplo de implementación programa Patrón_estrategia ; {$CONSOLA DE TIPO DE APLICACIÓN} tipo IStrategy = interfaz [ '{6105F24C-E5B2-47E5-BE03-835A894DEB42}' ] algoritmo de procedimiento ; fin ; TConcreteStrategy1 = clase ( TInterfacedObject , IStrategy ) Algoritmo de procedimiento público ; fin ; procedimiento TConcreteStrategy1 . algoritmo ; begin Writeln ( 'TConcreteStrategy1.Algorithm' ) ; fin ; tipo TConcreteStrategy2 = clase ( TInterfacedObject , IStrategy ) algoritmo de procedimiento público ; fin ; procedimiento TConcreteStrategy2 . algoritmo ; begin Writeln ( 'TConcreteStrategy2.Algorithm' ) ; fin ; tipo TContext = clase privada FStrategy : IStrategy ; procedimiento público ContextMethod ; propiedad Estrategia : IStrategy leer FStrategy escribir FStrategy ; fin ; procedimiento TContexto . método de contexto ; comenzar FStrategy . algoritmo ; fin ; var Contexto : TContexto ; comenzar Contexto : = TContext . crear ; prueba Contexto . Estrategia := TConcreteStrategy1 . crear ; contexto _ método de contexto ; contexto _ Estrategia := TConcreteStrategy2 . crear ; contexto _ método de contexto ; finalmente Contexto . Gratis ; fin ; fin _Ejemplos de JavaScript
Ejemplo de implementación // Estrategia de "interfaz" función Estrategia () { esto . exec = función () {}; }; // implementar estrategia // mostrar el mensaje en la barra de estado del navegador // (no compatible con todos los navegadores) function StrategyWindowStatus () { this . exec = función ( mensaje ) { ventana . estado = mensaje ; }; }; Estado de la ventana de estrategia . prototipo = nueva estrategia (); Estado de la ventana de estrategia . prototipo _ constructor = estado de la ventana de estrategia ; // mostrar el mensaje a través de una ventana emergente // (puede ser bloqueado por el navegador) function StrategyNewWindow () { this . exec = función ( mensaje ) { var win = ventana . abierto ( "" , "_blank" ); ganar _ documento _ escribir ( "<html>" + mensaje + "</html>" ); }; }; EstrategiaNuevaVentana . prototipo = nueva estrategia (); EstrategiaNuevaVentana . prototipo _ constructor = EstrategiaNuevaVentana ; // mostrar mensaje usando la función de ventana modal StrategyAlert () { this . exec = función ( mensaje ) { alerta ( mensaje ); }; }; Alerta de estrategia . prototipo = nueva estrategia (); Alerta de estrategia . prototipo _ constructor = alerta de estrategia ; // Contexto función Contexto ( estrategia ) { esto . exec = función ( mensaje ) { estrategia . exec ( mensaje ); }; } // uso var showInWindowStatus = nuevo Contexto ( nuevo StrategyWindowStatus () ); var showInNewWindow = nuevo Contexto ( nueva EstrategiaNuevaVentana () ); var showInAlert = nuevo Contexto ( new StrategyAlert () ); mostrar el estado de la ventana . exec ( "mensaje" ); mostrarEnNuevaVentana . exec ( "mensaje" ); mostrarEnAlerta . exec ( "mensaje" );Ejemplos en PHP
Ejemplo de implementación <?php interface NamingStrategy { function createName ( $filename ); } class ZipFileNamingStrategy implementa NamingStrategy { function createName ( $filename ) { return "http://downloads.foo.bar/ { $filename } .zip" ; } } class TarGzFileNamingStrategy implementa NamingStrategy { function createName ( $ nombre de archivo ) { return "http://downloads.foo.bar/ { $ nombre de archivo } .tar.gz" ; } } clase Contexto { private $namingStrategy ; function __construct ( NamingStrategy $estrategia ) { $this -> namingStrategy = $estrategia ; } función ejecutar () { $url [] = $this -> namingStrategy -> createName ( "Calc101" ); $url [] = $this -> namingStrategy -> createName ( "Stat2000" ); devolver $url ; } } if ( strstr ( $_SERVER [ "HTTP_USER_AGENT" ], "Win" )) $context = new Context ( new ZipFileNamingStrategy ()); else $contexto = nuevo Contexto ( new TarGzFileNamingStrategy ()); $contexto -> ejecutar (); ?>Ejemplo en Python 2.7
Ejemplo de implementación clase Personas ( objeto ): herramienta = Ninguno def __init__ ( self , nombre ): self . nombre = nombre def setTool ( self , herramienta ): self . herramienta = herramienta def escribir ( auto , texto ): auto . herramienta _ escribir ( propio . nombre , texto ) class ToolBase : """ `Writing Tool` Algorithm Family """ def write ( self , name , text ): aumentar NotImplementedError () class PenTool ( ToolBase ): """Pen""" def write ( self , name , text ): print u ' %s (pen) %s ' % ( name , text ) clase BrushTool ( ToolBase ): """Brush""" def write ( self , name , text ): print u ' %s (con pincel) %s ' % ( name , text ) clase Estudiante ( Personas ): herramienta """Estudiante""" = PenTool () clase Pintor ( Personas ): herramienta """Artista""" = BrushTool () máxima = Estudiante ( u 'Maxim' ) máxima . escribe ( u 'Estoy escribiendo una conferencia sobre el patrón de estrategia' ) # Maxim (con un bolígrafo) Estoy escribiendo una conferencia sobre el patrón de estrategia sasha = Pintor ( u 'Sasha' ) sasha . escribe ( u 'Dibujo una ilustración para el patrón de Estrategia' ) # Sasha (con un pincel) Dibujo una ilustración para el patrón de Estrategia # Sasha decidió convertirse en estudiante de sasha . setTool ( PenTool ()) sasha . escribe ( u 'No, prefiero escribir una sinopsis' ) # Sasha (con un bolígrafo) No, prefiero escribir una sinopsisEjemplo en rubí
Ejemplo de implementación requiere "interfaz" estrategia = interfaz { métodos_requeridos :uso } class StrategyOne def use puts "Strategy one" end implements Strategy end class StrategyTwo def use puts "Estrategia dos" end implements Strategy end class StrategyThree def use puts "Estrategia tres" end implements Strategy end clase Contexto attr_accessor :estrategia def inicializar estrategia @estrategia = estrategia final def usarEstrategia estrategia . usar fin fin contexto = contexto . nueva estrategia uno . nuevo contexto . usarEstrategia contexto _ estrategia = estrategia dos . nuevo contexto . usarEstrategia contexto _ estrategia = EstrategiaTres . nuevo contexto . usarEstrategia
Patrones de diseño | |
---|---|
Principal | |
Generativo | |
Estructural | |
conductual | |
Programación en paralelo |
|
arquitectónico |
|
Plantillas Java EE | |
Otras plantillas | |
Libros | |
Alusiones personales |