Пример с отпуском
Мы можем поехать в отпуск на самолете, поезде или машине. Это будут разные стратегии. Посмотрим, как это реализовать, с помощью соответствующего паттерна.
Main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
program Strategy; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, uStrategyVacation in 'uStrategyVacation.pas'; var v: TVacation; begin try v := TVacation.Create(); try v.Transport := TStrategyAirplane.Create(); v.Move(); // v.Transport := TStrategyTrain.Create(); v.Move(); // v.Transport := TStrategyCar.Create(); v.Move(); Readln; finally v.Free(); end; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
Интерфейсы и классы стратегий
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
unit uStrategyVacation; interface uses System.SysUtils; type IStrategyTransport = interface procedure Go(); end; TStrategyAirplane = class(TInterfacedObject, IStrategyTransport) procedure Go(); end; TStrategyTrain = class(TInterfacedObject, IStrategyTransport) procedure Go(); end; TStrategyCar = class(TInterfacedObject, IStrategyTransport) procedure Go(); end; TVacation = class FTransport: IStrategyTransport; public procedure Move(); property Transport: IStrategyTransport read FTransport write FTransport; end; implementation { TStrategyCar } procedure TStrategyCar.Go; begin Writeln('driving'); end; { TStrategyAirplane } procedure TStrategyAirplane.Go; begin Writeln('flying'); end; { TStrategyTrain } procedure TStrategyTrain.Go; begin Writeln('too - too'); end; { TVacation } procedure TVacation.Move; begin FTransport.Go(); end; end. |
Канонический пример
Есть у нас некоторый интерфейс с методом “Algorhytm”, есть классы, которые реализуют этот метод по разному, и есть класс контекста, в котором, подменяя стратегию, мы получаем разные реализации метода “Algorhytm”.
Main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
program Strategy; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, uStrategy in 'uStrategy.pas', uStrategyVacation in 'uStrategyVacation.pas'; var c: TContext; begin try c := TContext.Create(); try // use one strategy c.Strategy := TConcreteStrategy1.Create(); c.ContextMethod(); // now use another one strategy c.Strategy := TConcreteStrategy2.Create(); c.ContextMethod(); Readln; finally c.Free(); end; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
Собственно стратегии
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
unit uStrategy; interface uses System.SysUtils; type IStrategy = interface procedure Algorhytm(); end; TConcreteStrategy1 = class(TInterfacedObject, IStrategy) public procedure Algorhytm(); end; TConcreteStrategy2 = class(TInterfacedObject, IStrategy) public procedure Algorhytm(); end; TContext = class FStrategy: IStrategy; public procedure ContextMethod(); property Strategy: IStrategy read FStrategy write FStrategy; end; implementation {TConcreteStrategy1} procedure TConcreteStrategy1.Algorhytm; begin Writeln('TConcreteStrategy1.Algorhytm'); end; {TConcreteStrategy2 } procedure TConcreteStrategy2.Algorhytm; begin Writeln('TConcreteStrategy2.Algorhytm'); end; { TContext } procedure TContext.ContextMethod; begin FStrategy.Algorhytm; end; end. |