Strategy mode
origin
Delphi's STRATEGY mode is expanded on the basis of STRATEGY. For more information on STRATEGY mode, please refer to "Design Pattern Page 208"
Purpose
Define a series of algorithms, encapsulate them one by one, and make them interchangeable. This pattern makes the algorithm independent of changes in the client using it.
motivation
? Different strategies can be dynamically transformed as needed. ? Better encapsulate multiple behaviors and algorithm structures without allowing client programs to directly interfere? Select the correct behavior method through relevant conditional statements. The
Template method uses inheritance to transform parts of the algorithm. Strategies use proxies and combinations to transform all algorithms and support dynamic transformations. In the future, the context object will be used to dynamically allocate specific algorithms at runtime. Similarly, by using the context object, the client class will be separated from the dependent algorithm interface, and more generalized interfaces can be provided through the context object. In the same sense, through
the context and
strategy interfaces, system-wide related algorithms can be designed and provided in the future to implement specific applications without changing the interfaces.
Strategies also let you create a single, simple, maintainable class framework. Class frameworks rely on inheritance.
application
Implementation
The following example calculates the monthly interest rate for a credit card.
Strategy mode encapsulates and accesses interfaces through the unique abstract class TfinanzeCharge and provides different algorithms to calculate monthly interest rates. TregularCharge and TPReferredCharge encapsulate different specific algorithms for the monthly interest rate calculation of credit cards. TmonthlyCharge implements the TcontextCharge interface and configures different policy objects. TconntextCharge becomes the midfield engine of client objects and strategy objects, which helps to reduce the dependence of client objects and strategies/objects.
// Strategy interface ( abstract class) TFinanzeCharge = class public //Return the calculated result
function getCharge(const Balance: double): double; virtual; abstract; end;
// Specific strategy TRegularCharge = class(TFinanzeCharge) public
function getCharge(const Balance: double): double; override ; end;
// Specific strategy TPreferredCharge = class(TFinanzeCharge) public
function getCharge(const Balance: double): double; override; end;The client program relies on the context interface to schedule the specified strategy. However, since the context interface is generated for the client program, the client program must know the available policies/objects. If the context cannot return a valid instance, you can optionally choose a method implementation with a default strategy.
// Context interface TChargeContext = class public
function ComputeCharges(const Balance: double): double; virtual; abstract ; end;
// The specific context class TmonthlyCharges serves as the midfield engine for the client object and the strategy object, and is passed in its constructor A specific interest rate calculation instance is set up.
This class acts as a mediator between the client and the strategy classes, and is configured by using composition and passing an instance of a concrete finance charge in its constructor.
TMonthlyCharges = class(TChargeContext) private FFinanzeCharge: TFinanzeCharge; public//Interface
function accessed by client program ComputeCharges(const Balance: double): double; override; // constructor configures the context object constructor Create(aFinanzeCharge: TFinanzeCharge); virtual; destructor Destroy; override; end;---implementation
// TRegularCharge function TRegularCharge.getCharge(const Balance: double): double;begin result := Balance * (REG_RATE / 12);end;
// TPreferredCharge function TPreferredCharge.getCharge(const Balance: double): double;begin // this could be a complex algorithm that takes into account the // credit card holder's buying patterns and reward points accumulated. result := Balance * (PREFERRED_RATE / 12);end;
// Concrete Context // TMonthlyCharges constructor TMonthlyCharges.Create(aFinanzeCharge: TFinanzeCharge);begin inherited Create; // aFinanzeCharge configures the context object // this class takes ownership of aFinanzeCharge (will destroy it) FFinanzeCharge := aFinanzeCharge;end;destructor TMonthlyCharges.Destroy; begin FFinanzeCharge.Free; inherited Destroy;end;function TMonthlyCharges.ComputeCharges(const Balance: double): double;begin result := FFinanzeCharge.getCharge(Balance);end;
Delphi example