Modo de estrategia de programación en modo Delphi (continuación)
Liu Yi
1.3 Aplicación del modelo de estrategia en el sistema de gestión hotelera.
En los sistemas de gestión hotelera, normalmente el precio de una habitación no es estático. Deben existir estrategias de venta diferentes para los alojamientos fuera de temporada y temporada alta, para clientes antiguos y nuevos, para huéspedes individuales y para grupos. Evidentemente, la estrategia de ventas determina la oferta. Sin embargo, el sistema de cotización basado en la estrategia de ventas no puede vincularse a un cliente específico, porque solo independizando el sistema de cotización basado en la estrategia de ventas se puede garantizar su reutilización y mantenibilidad. Por ejemplo: por un lado, un sistema de cotizaciones satisface las necesidades de múltiples clientes, como la consulta de tarifas de habitaciones preferenciales y la liquidación de habitaciones, por otro lado, satisface las necesidades de ajustar constantemente nuevas estrategias de ventas. Esto realmente puede lograr reutilización y mantenibilidad. . Para los requisitos de diseño anteriores, es mejor elegir el modo de estrategia. El patrón Estrategia permite cambios de algoritmo independientemente del cliente que lo utilice. El programa de muestra es un módulo de consulta de precios de vivienda preferencial basado en el modelo estratégico, que incluye un sistema de cotización basado en la estrategia de ventas y una interfaz de consulta de precios de vivienda preferencial. Por supuesto, la interfaz de consulta de precios preferenciales es solo uno de los clientes del sistema de cotización, y otros clientes también pueden utilizar el sistema de cotización. El diseño del módulo de consulta de precios preferenciales se muestra en la Figura 1‑6. Incluye: · Clase de estrategia de ventas TSaleStrategy, que es una clase base abstracta para clases de estrategia de ventas específicas. · 3 categorías de estrategia de ventas específicas: TVipStrategy (estrategia de ventas de tarjetas VIP), TTeamStrategy (estrategia de ventas en equipo), TSeasonStrategy (estrategia de ventas estacional). · Clase de cotización TPRiceContext, que es el contexto en este patrón de estrategia y contiene una referencia a TStrategy. · La clase de cliente TClient es una clase de formulario, que es la interfaz para consultar el precio de la vivienda. Figura 1‑6 El programa de muestra 1‑1 para el módulo de consulta de tarifas de habitaciones preferenciales basado en el patrón de estrategia es el código fuente de la unidad HotelSaleStrategy. Esta unidad contiene la lógica de negocios del sistema de cotización basado en la estrategia de ventas y se implementa utilizando el patrón de estrategia. . Como clase base abstracta de la estrategia de ventas, TSaleStrategy tiene como objetivo proporcionar una interfaz común. La función abstracta virtual SalePrice es una de esas interfaces. Dado que las tres estrategias de ventas específicas se formulan en función de la temporada, la tarjeta VIP y el tamaño del equipo, el diseño de parámetros de la interfaz de clase base SalePrice debe satisfacer las diferentes necesidades de las tres clases derivadas. La función SalePrice de TSaleStrategy se declara de la siguiente manera: function SalePrice(price:Currency;value:integer):Currency; virtual; Su primer parámetro representa el precio fijo entrante y el segundo parámetro representa las condiciones preferenciales entrantes. para diferentes clases derivadas. En la estrategia de ventas estacional TSeasonStrategy, este parámetro se expresa como el mes de registro; en la estrategia de ventas de tarjetas VIP TVIPStrategy, este parámetro se expresa como el tipo de tarjeta VIP; en la estrategia de ventas del equipo TTeamStrategy, este parámetro se expresa como el; número de personas en el equipo. Descubrimos que todos estos parámetros pueden usar tipos enteros, por lo que en la clase base, se usa inteligentemente un parámetro de valor para resolver los diferentes requisitos de parámetros de la clase derivada. De esta manera, TPriceContext puede poner datos directamente en parámetros y pasarlos a diferentes operaciones de estrategia de ventas, evitando la redundancia de parámetros. {TPriceContext }función TPriceContext.GetPrice(price:Currency;value:integer):Currency;begin result:=Strategy.SalePrice(price,value);end;TPriceContext juega un papel contextual en este modo de estrategia y es responsable de hacer referencia a las ventas. estrategia Diferentes instancias del objeto llaman a la interfaz SalePrice para configurar dinámicamente el algoritmo de descuento específico y devolver el precio de venta real. Debido al intermediario de TPriceContext, el cliente no necesita saber cómo se implementa la estrategia de ventas específica. De manera similar, cuando la estrategia de ventas se actualiza y ajusta, no tendrá ningún impacto en el programa del cliente; Programa de muestra 1‑1 Código fuente de la unidad HotelSaleStrategy HotelSaleStrategy; la interfaz utiliza SysUtils, Windows, mensajes, clases, gráficos, controles, formularios, diálogos; escriba TSaleStrategy = clase (TObject) función pública Precio de Venta (precio: Moneda; valor: entero): Moneda ; virtual; resumen; fin; TSeasonStrategy = función pública de clase (TSaleStrategy) Precio de venta (precio: moneda; valor: entero): moneda; anulación; fin; TVIPStrategy = función pública de clase (TSaleStrategy); Precio de venta (precio: moneda; valor: entero): moneda; fin; TPriceContext = clase (TObject) FStrategy privado: TSaleStrategy; procedimiento SetStrategy (Valor: TSaleStrategy); función pública GetPrice (precio: Moneda; valor: entero): Propiedad de moneda Estrategia: TSaleStrategy leer FStrategy escribir SetStrategy; TSeasonStrategy.SalePrice(price:Currency;value:integer):Currency;begin //Estrategia de ventas estacional {15% de descuento en febrero, marzo y noviembre, 10% de descuento en abril y junio. 8. 9,5% de descuento en septiembre. } valor de caso de 2,3,11:resultado:=precio*0,85; 4,6:resultado:=precio*0,9; 8,9:resultado:=precio*0,95; TVIPStrategy }función TVIPStrategy.SalePrice(price:Currency;value:integer):Currency;begin //Estrategia de venta de tarjetas VIP{ 0:Tarjeta VIP Silver 10% de descuento 1:Tarjeta VIP Gold 20% de descuento 2:Tarjeta VIP Diamond 30% de descuento} valor de caja de 0:resultado:=precio*0,9; =precio*0.7; fin;fin;{TTeamStrategy }función TTeamStrategy.SalePrice(price:Currency;value:integer):Currency;begin // Estrategia de ventas en equipo {10 % de descuento para un equipo de 3 a 5 personas; 20 % de descuento para un equipo de 6 a 10 personas; un equipo de 11-20 personas; 20 40% de descuento para grupos de más de 1 persona. } resultado:=precio; si (valor<6) y (valor>2) entonces resultado:=precio*0.9; si (valor<11) y (valor>5) entonces resultado:=precio*0.8; 21) y (valor>10) entonces resultado:=precio*0.7 si (valor>20) entonces resultado:=precio*0.6;end;{TPriceContext }función TPriceContext.GetPrice(precio:Moneda;valor:entero):Moneda;comenzar resultado:=Strategy.SalePrice(precio,valor);fin;procedimiento TPriceContext.SetStrategy(Valor: TSaleStrategy);comenzar FStrategy:=Valor;fin;fin. El programa de cliente del módulo de consulta de tarifa de habitación preferencial se muestra en el Programa de muestra 1-2. El programa proporciona una interfaz de selección de usuario para que el solicitante pueda elegir un plan preferencial. Una vez que seleccione las condiciones preferenciales y tarifas públicas, haga clic en el botón "Consultar Tarifas Preferenciales" para obtener las tarifas con descuento. El efecto de operación real se muestra en la Figura 1-7. Programa de muestra 1-2 Unidad de código fuente ClientForm La interfaz ClientForm utiliza Windows, Mensajes, SysUtils, Variantes, Clases, Gráficos, Controles, Formularios, Diálogos, StdCtrls, ExtCtrls, HotelSaleStrategy, ComCtrls,DateUtils tipo TClient = class(TForm) RadioGroup1: TRadioGroup; btnCheck: TButton; btnExit: TLabel; dtpDate: TComboBox: TEdit: TLabel; TLabel; procedimiento FormCreate(Remitente: TObject); procedimiento btnCheckClick (Remitente: TObject); procedimiento FormDestroy (Remitente: TObject); procedimiento FVIPStrategy: TSaleStrategy; TSaleStrategy; TPriceContext; público { Declaraciones públicas } end;var Cliente: TClient;implementación{$R *.dfm}procedimiento TClient.FormCreate(Remitente: TObject);begin FSeasonStrategy:=TSeasonStrategy.Create;=TVIPStrategy.Create; ; FPriceSys:=TPriceContext.Create;end;procedimiento TClient.btnCheckClick(Remitente: TObject);var i:integer; precio:Moneda;comenzar caso RadioGroup1.ItemIndex de 0:comenzar FPriceSys.Strategy:=FSeasonStrategy i:=MonthOf(dtpDate; .FechaHora); fin; 1:comienzo FPriceSys.Strategy:=FVIPStrategy; i:=cmbVIP.ItemIndex; 2:comenzar FPriceSys.Strategy:=FTeamStrategy; i:=StrToInt(edtCount.Text final); 300; //La habitación estándar clase A cuesta 300 yuanes 1:precio:=500; //Habitación estándar clase B 500 yuanes 2:precio:=800; //Habitación VIP 800 yuanes 3:precio:=1000; //Suite de negocios 1000 yuanes 4:precio:=2000; // Suite de lujo 2000 yuanes edtPrecio. Texto:=CurrToStr(FPriceSys.GetPrice(precio,i));end;procedimiento TClient.FormDestroy(Remitente: TObject); comenzar FPriceSys.Free; FSeasonStrategy.Free; FVIPStrategy.Free; fin; procedimiento TClient.btnExitClick (Remitente: TObject); edtCount.Enabled:=false; cmbVIP.Enabled:=false; caso RadioGroup1.ItemIndex de 0:dtpDate.Enabled:=true; 1:cmbVIP.Enabled:=true; end Figura 1-7 La interfaz de ejecución real del módulo de consulta de precios preferenciales.
1.4 Resumen de la práctica
A través de la demostración y el análisis de los ejemplos anteriores, analizamos más a fondo el patrón de estrategia de la siguiente manera: · El patrón de estrategia proporciona una forma de gestionar un conjunto de algoritmos. La jerarquía de clases de estrategia define una serie de algoritmos o comportamientos reutilizables para TContext. La clase base TStrategy extrae las funciones comunes en estos algoritmos, y las clases derivadas enriquecen las diferencias y tipos de algoritmos a través de la herencia y evitan la duplicación de código. · Si no separa el algoritmo del contexto en el que se utiliza el algoritmo y genera directamente una clase derivada de la clase TContext que contiene el algoritmo y le da diferentes comportamientos, esto codificará el comportamiento en TContext, y Separe la implementación del algoritmo de TContext. Las implementaciones están mezcladas, lo que hace que TContext sea difícil de entender, mantener y ampliar. El resultado final es un montón de clases relacionadas, la única diferencia entre ellas es el algoritmo que utilizan. Obviamente, la relación de herencia de clases es una asociación fuerte, y la relación de herencia no puede cambiar dinámicamente el algoritmo, mientras que la relación de composición de objetos es una asociación débil. Al combinar objetos de clases de estrategia, el algoritmo puede evolucionar independientemente del entorno (TContext). en el que se utiliza el algoritmo. · Utilice el patrón de estrategia para refactorizar códigos de programa que utilizan una gran cantidad de declaraciones de rama condicional. Cuando se acumulan diferentes comportamientos en una clase, es difícil evitar el uso de declaraciones condicionales para seleccionar el comportamiento apropiado. Encapsular el comportamiento en clases de políticas separadas elimina estas declaraciones condicionales. · Demasiados algoritmos pueden dar como resultado una gran cantidad de objetos de política. Para reducir la sobrecarga del sistema, el estado que depende del entorno del algoritmo generalmente se puede guardar en el cliente y TStrategy se implementa como un objeto sin estado que puede ser compartido por varios clientes. TContext mantiene cualquier estado externo. TContext pasa este estado en cada solicitud al objeto TStrategy. Por ejemplo, en el programa de muestra, guardo el mes de registro de estado externo de TSeasonStrategy, el tipo de tarjeta VIP de estado externo de TVIPStrategy y el tamaño del equipo de estado externo de TTeamStrategy en el cliente, y paso estos estados a la clase de estrategia de ventas a través de TPriceContext. La ventaja de esto es que la clase de estrategia de ventas se vuelve sin estado y puede ser compartida por otros módulos, como el módulo de liquidación de habitaciones. · Independientemente de si el algoritmo implementado por cada estrategia específica es simple o complejo, todos comparten la interfaz definida por TStrategy. Por lo tanto, es probable que algunas políticas específicas no utilicen toda la información que se les pasa a través de esta interfaz. Si diseño la interfaz de TSaleStrategy así en el programa de muestra:
Precio de oferta(precio:Moneda;Mes:entero;VIP:entero;
Recuento: entero): Moneda;
Algunos de estos parámetros nunca serán utilizados por determinadas clases de estrategias de ventas. Esto significa que a veces TContext creará e inicializará parámetros que nunca se utilizarán. Si existe tal problema y no puede utilizar las técnicas del programa de muestra, solo puede adoptar un método estrechamente acoplado entre TStrategy y TContext.
Se pueden descargar más artículos relacionados y códigos fuente de programas de muestra desde el sitio web del autor: http://www.liu-yi.net