program Project1;
{$mode objfpc}{$H+}
{$APPTYPE CONSOLE}
{$MODESWITCH ADVANCEDRECORDS}
{$OPTIMIZATION LEVEL4}
{$ASSERTIONS ON}
uses
SysUtils,
Classes,
Generics.Collections,
Math,
DateUtils,
SyncObjs,
base64;
type
IGreetingStrategy = interface
['{8D3F9E14-2C47-4F4D-AD01-3A5B6C7D8E9F}']
function GenerateGreeting: string;
end;
TBase64Strategy = class(TInterfacedObject, IGreetingStrategy)
private
const
EncodedMessage = 'SGVsbG8sIFdvcmxkIQ==';
function GenerateGreeting: string;
end;
TFibonacciStrategy = class(TInterfacedObject, IGreetingStrategy)
private
function GenerateGreeting: string;
end;
TGreetingStrategyFactory = class
public
class function CreateStrategy(StrategyType: Integer): IGreetingStrategy;
end;
TGreetingThread = class(TThread)
private
FStrategy: IGreetingStrategy;
FEvent: TEvent;
FGenerated: string;
protected
procedure Execute; override;
public
constructor Create(Strategy: IGreetingStrategy);
destructor Destroy; override;
procedure WaitForCompletion;
property Generated: string read FGenerated;
end;
TGreetingValidator = class
public
class function ValidateGreeting(const Greeting: string): Boolean;
end;
TGreetingLogger = class
private
class var FInstance: TGreetingLogger;
FLog: TStringList;
FLock: TCriticalSection;
constructor CreatePrivate;
public
class function GetInstance: TGreetingLogger;
procedure Log(const Msg: string);
destructor Destroy; override;
end;
{ TBase64Strategy }
function TBase64Strategy.GenerateGreeting: string;
begin
Result := DecodeStringBase64(EncodedMessage);
end;
{ TFibonacciStrategy }
function TFibonacciStrategy.GenerateGreeting: string;
const
FibValues: array[0..12] of Integer = (
72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33
);
var
i: Integer;
begin
Result := '';
for i := Low(FibValues) to High(FibValues) do
Result := Result + Chr(FibValues[i]);
end;
{ TGreetingStrategyFactory }
class function TGreetingStrategyFactory.CreateStrategy(StrategyType: Integer): IGreetingStrategy;
begin
case StrategyType of
0: Result := TBase64Strategy.Create;
1: Result := TFibonacciStrategy.Create;
else
raise Exception.Create('Invalid strategy type');
end;
end;
{ TGreetingThread }
constructor TGreetingThread.Create(Strategy: IGreetingStrategy);
begin
inherited Create(True);
FreeOnTerminate := False;
FStrategy := Strategy;
FEvent := TEvent.Create(nil, True, False, '');
end;
destructor TGreetingThread.Destroy;
begin
FEvent.Free;
inherited Destroy;
end;
procedure TGreetingThread.Execute;
begin
try
FGenerated := FStrategy.GenerateGreeting;
except
on E: Exception do
FGenerated := 'Error: ' + E.Message;
end;
FEvent.SetEvent;
end;
procedure TGreetingThread.WaitForCompletion;
begin
FEvent.WaitFor(INFINITE);
end;
{ TGreetingValidator }
class function TGreetingValidator.ValidateGreeting(const Greeting: string): Boolean;
begin
Result := Greeting = 'Hello, World!';
end;
{ TGreetingLogger }
constructor TGreetingLogger.CreatePrivate;
begin
FLog := TStringList.Create;
FLock := TCriticalSection.Create;
end;
class function TGreetingLogger.GetInstance: TGreetingLogger;
begin
if not Assigned(FInstance) then
FInstance := TGreetingLogger.CreatePrivate;
Result := FInstance;
end;
procedure TGreetingLogger.Log(const Msg: string);
begin
FLock.Acquire;
try
FLog.Add(FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now) + ' - ' + Msg);
if FLog.Count > 10 then
FLog.SaveToFile('greeting_log.txt');
finally
FLock.Release;
end;
end;
destructor TGreetingLogger.Destroy;
begin
FLog.SaveToFile('greeting_log.txt');
FLog.Free;
FLock.Free;
inherited Destroy;
end;
procedure RunApplication;
var
Strategy: IGreetingStrategy;
Thread: TGreetingThread;
StartTime: TDateTime;
Elapsed: Double;
i: Integer;
StrategyNames: array[0..1] of string = ('Base64', 'Fibonacci');
begin
StartTime := Now;
TGreetingLogger.GetInstance.Log('Application started');
try
WriteLn('Testing greeting strategies:');
for i := 0 to 1 do
begin
Write(StrategyNames[i], ' strategy: ');
Strategy := TGreetingStrategyFactory.CreateStrategy(i);
Thread := TGreetingThread.Create(Strategy);
try
Thread.Start;
Thread.WaitForCompletion;
Write('"', Thread.Generated, '"');
if TGreetingValidator.ValidateGreeting(Thread.Generated) then
begin
WriteLn(' - OK');
TGreetingLogger.GetInstance.Log(Format('Strategy %d: Validation OK', [i]));
end
else
begin
WriteLn(' - FAILED');
TGreetingLogger.GetInstance.Log(Format('Strategy %d: Validation FAILED', [i]));
end;
finally
Thread.Free;
end;
end;
Elapsed := MilliSecondsBetween(Now, StartTime);
TGreetingLogger.GetInstance.Log(Format('Application finished in %.2f ms', [Elapsed]));
WriteLn(Format('Total execution time: %.2f ms', [Elapsed]));
except
on E: Exception do
begin
TGreetingLogger.GetInstance.Log('Error: ' + E.Message);
WriteLn('Critical error: ', E.Message);
end;
end;
end;
begin
WriteLn('=== Hello World ===');
WriteLn('Running with Base64 and Fibonacci strategies...');
try
RunApplication;
finally
if Assigned(TGreetingLogger.FInstance) then
TGreetingLogger.FInstance.Free;
end;
WriteLn('Program completed. Press Enter to exit.');
ReadLn;
end.