programas - Patrón de estrategia de C++
programacion basica c++ (5)
El uso de punteros de función para implementar la estrategia es una especie de caso degenerado de la versión basada en herencia. El núcleo esencial del patrón es, como saben, poder suministrar o modificar un componente de algún proceso en tiempo de ejecución. Ese componente puede ser una función, o puede ser un objeto. Si la estrategia consta de varios bits, una versión basada en herencia es realmente más agradable, ya que un objeto puede empaquetar varios métodos juntos; Si solo hay una pieza, entonces los punteros de función son bastante buenos.
En el pasado, he visto el patrón de estrategia explicado como un mecanismo que permite al usuario de una función / clase proporcionar su propia funcionalidad para esa función / clase.
Siempre se me había enseñado que la forma de implementar el patrón era mediante el uso de punteros de función en sus clases / funciones y llamándolos internamente, lo que permitía al programador proporcionar su propia "estrategia" que sería utilizada internamente por esas funciones y objetos.
Mirando a mi alrededor más recientemente, veo que el patrón de la estrategia siempre parece explicarse / definirse a través del uso de una jerarquía de herencia como tal:
Implementación de patrones de estrategia.
¿Es esta una diferencia de opinión / implementación, o la función de puntero no es realmente una variación del patrón de estrategia? Estoy más interesado, por lo que no confundo a la gente cuando comento o explico mi código :)
En mi opinión, el patrón starategy se puede implementar utilizando:
- Las plantillas y las expresiones constantes en tiempo de compilación (de inicio temprano, pueden no llamarse realmente como patrón de estrategia ).
- Mecanismo de función virtual (Sí, asignando diferentes clases derivadas a una referencia / puntero).
- Punteros de funcion
- Puntero a miembros ( métodos ) de una clase.
- Usando std :: function, y usando lambdas.
En mi opinión, la implementación del patrón de estrategia utilizando punteros de función se realiza en idiomas que no tienen soporte para OOP (como C).
En los idiomas que admiten OOP, se implementa mejor utilizando clases: herencia, funciones virtuales (es decir, polimorfismo de tiempo de ejecución), interfaz, etc. Por lo general, este es un patrón de estrategia en tiempo de ejecución, lo que significa que puede cambiar el comportamiento del programa simplemente cambiando a otro patrón de estrategia, en tiempo de ejecución.
En C ++, también hay un patrón de estrategia en tiempo de compilación, comúnmente conocido como diseño basado en políticas .
En cualquier caso, las clases pueden mantener estados, mientras que los punteros de función no pueden. Esa es la mayor ventaja en el uso de clases.
Los objetos de interfaz pueden tener estado y, por lo tanto, mantener las variables miembro. Los punteros de función no pueden.
Simplemente tiene que usar la herencia en idiomas sin punteros a función (lea: Java).
Personalmente, preferiría std::function
sobre punteros de función brutos, ya que acepta una gama más amplia de argumentos y le permite mantener el estado en el objeto de estrategia.
Además, si ya conoce la estrategia en tiempo de compilación, incluso puede usar plantillas y así ahorrar espacio y tiempo de ejecución de punteros de función y objetos de std::function
.