DesignPatterns. Mediator

Объекты связаны друг с другом через посредника. Так называемая слабая связанность.

program MediatorPattern;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uMediator in 'uMediator.pas';

var
  Stas: TColleague;
  Masha: TColleague;
  chat: TMediator;

begin
  chat := TMediator.Create();
  chat.AddParticipant(TColleague.Create(1, 'Stas'));
  chat.AddParticipant(TColleague.Create(2, 'Masha'));
  Stas := chat.Colleague[0];
  Masha := chat.Colleague[1];
  try
    Stas.Send('Привет, Маша, пойдем гулять?', Masha);
    Masha.Send('Привет, Стас, конечно!', Stas);
    ReadLn;
  finally
    chat.Free();
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Mediator

DesignPatterns. ChainOfResponsibilities

Есть цепочка объектов. Одно звено выполняет одни операции, другое – другие.

program ChainsOfResponsibilities;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uChainsOfResponsibilities in 'uChainsOfResponsibilities.pas';

var
  d: TDirector;
  m: TManager;
  w: TWorker;
  p: TPurchase;

begin
  d := TDirector.Create();
  m := TManager.Create();
  w := TWorker.Create();
  p := TPurchase.Create(5);
  try
    w.SetNextApprover(m);
    m.SetNextApprover(d);
    w.ProcessRequest(p); // trying to buy
    Readln;
  finally
    d.Free();
    m.Free();
    w.Free();
    p.Free();
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. ChainOfResponsibilities

DesignPatterns. Proxy

Для распределения нагрузки. Есть интерфейс, который поддерживает основной класс и его заместитель. Легкие операции может выполнять заместитель, а тяжелые – основной класс.

program Proxy;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uProxy in 'uProxy.pas';

var
  server: TServer;
  si: IServerInterface;

begin
  server := TServer.Create();
  si := TProxy.Create(server);
  try
    si.LightOperation();
    si.HeavyOperation();
    Readln;
  finally
    server.Free();
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Proxy

DesignPatterns. Flyweight

“Приспособленец”. Если объект с такими признаками есть, в нашей коллекции, берем его, если нет, создаем. Работает совместно с фабрикой

program Flyweight;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uFlyweight in 'uFlyweight.pas';

var
  bookFactory: TBookFactory;

begin
  bookFactory := TBookFactory.Create();
  try
    bookFactory.GetBookToRead('Alice in wonderland');
    bookFactory.GetBookToRead('Flying on Cooko''s nest');
    bookFactory.GetBookToRead('Delphi Cookbook');
    bookFactory.GetBookToRead('Delphi Cookbook');
    Readln;
  finally
    bookFactory.Free();
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Flyweight

Delphi. UniGUI. PagedGrid with summary

UniGUI позволяет разбивать dataset на страницы, для этого нужно включить в свойствах грида WebOptions -> Paged := true

Выглядеть это может так

Предыдущий способ подсчета итоговых результатов не подойдет, потому что сумма будет посчитана только по тем записям, которые видны. Итак, что же делать в этом случае? Для этого нам их просто надо посчитать в другом месте, например так

procedure TMainForm.CalcTotals;
var
  B : TBookmark;
begin
  if not FInited then Exit;
  ClientDataSet1.DisableControls;
  B := ClientDataSet1.GetBookmark;
  try
    GTotal := 0;
    GTotalPrice := 0.0;

    ClientDataSet1.First;
    while not ClientDataSet1.Eof do
    begin
      GTotal := GTotal + ClientDataSet1.FieldByName('Quantity').AsInteger;
      GTotalPrice := GTotalPrice +
                    ( ClientDataSet1.FieldByName('UnitPrice').AsFloat * ClientDataSet1.FieldByName('Quantity').AsInteger );

      ClientDataSet1.Next;
    end;
  finally
    ClientDataSet1.GotoBookmark(B);
    ClientDataSet1.FreeBookmark(B);
    ClientDataSet1.EnableControls;
  end;
end;

А в OnColumnSummaryResult грида сделать следующее

procedure TMainForm.UniDBGrid1ColumnSummaryResult(Column: TUniDBGridColumn;
  GroupFieldValue: Variant; Attribs: TUniCellAttribs; var Result: string);
begin
  if SameText(Column.FieldName, 'quantity') then
  begin
    Result:=Format('Total Units: %d', [GTotal]);
    Attribs.Font.Style:=[fsBold];
    Attribs.Font.Color:=clGreen;
  end
  else if SameText(Column.FieldName, 'unitprice') then
  begin
    Result:='Total Cost: '+FormatCurr('0,0.00 ', GTotalPrice) + FmtSettings.CurrencyString;
    Attribs.Font.Style:=[fsBold];
    Attribs.Font.Color:=clNavy;
  end;
end;

Где GTotal у нас объявлена как поле. Оно в принципе и понятно, считаем результаты, закидываем их в поля, а в выводе результатов берем информацию из полей.

Posted in Без рубрики | Comments Off on Delphi. UniGUI. PagedGrid with summary

DesignPatterns. Facade

Смысл этого паттерна в том, чтобы работать с одним объектом, вместо множества других. И в этом одном объекте содержатся ссылки на другие объекты. Выглядеть это может так

program Facade;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uFacade in 'uFacade.pas';

var
  foundation: TFoundation;
  floors: TFloors;
  roof: TRoof;
  building: TBuilding;

begin

  foundation := TFoundation.Create();
  floors := TFloors.Create();
  roof := TRoof.Create();
  building := TBuilding.Create(foundation, floors, roof);
  try
    Writeln(building.Build());
    Readln;
  finally
    foundation.Free();
    floors.Free();
    roof.Free();
  end;

end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Facade

Delphi. UniGUI. Grid with Summary

Сегодня посмотрим, как сделать грид со строкой Summary в конце. А сделать это очень просто, как и все в UniGUI. Выглядит это так

Сначала нам нужно посчитать итоговые результаты, делается это в событии OnColumnSummary

Continue reading
Posted in Без рубрики | Comments Off on Delphi. UniGUI. Grid with Summary

DesignPatterns. Decorator

Есть объект, выполняющий основную операцию. Требуется добавить дополнительную операцию до, после, либо вместо основной операции. Традиционный путь – через наследование приводит к комбинаторному взрыву подклассов. Другой подход (композиция) – создать новый класс декоратор со ссылкой на наш объект и вызвать основную операцию. А до нее, после или вместо вызвать необходимую нам дополнительную операцию.

В самом простом виде декорация могла бы выглядеть так. Пусть у нас есть некоторый главный объект, который выполняет некоторую главную операцию. И далее, нам нужно сделать что-то до выполнения главной операции.

program Decorator;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uDecorator in 'uDecorator.pas';

var
  m: TMainObject;
  d: TDecoratorBefore;
begin
  try
    m := TMainObject.Create();
    d := TDecoratorBefore.Create(m);
    try
      d.DoSmthBeforeAndMainOperation();
    finally
      m.Free();
      d.Free();
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Класс декоратора

Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Decorator

Delphi. Некоторые функции для работы с битами

Получение числа из байтовой строки Signed (если в старшем бите зашифрована информация о знаке, 1 это минус, 0 это плюс) и Unsigned

function GetNumberFromByteStringUnsigned(const s: AnsiString): extended;
var
  i, len: integer;
  mn: extended;
  p: Int64;
begin
  len := Length(s);
  Assert(len > 0);
  if len < 8 then
  begin
    p := 0;
    Move(s[1], p, len);
    Result := p;
  end
  else
  begin
    Result := Ord(s[1]);
    mn := 1;
    for i := 2 to len do
    begin
      mn := mn * 256;
      Result := Result + mn * Ord(s[i]);
    end;
  end;
end;

function GetNumberFromByteString(const s: AnsiString): extended;
var
  i, len: integer;
  mn: extended;
  p: Int64;
begin
  len := Length(s);
  Assert(len > 0);
  if len < 8 then
  begin
    p := 0;
    Move(s[1], p, len);
    if ord(s[len]) shr 7 = 1 then // отрицательная ветка, если старший бит равен 1
      Result := -((int64(1) shl (len * 8)) - p)
    else
      Result := p; // Иначе положительное число
  end
  else
  begin
    Result := Ord(s[1]);
    mn := 1;
    for i := 2 to len do
    begin
      mn := mn * 256;
      Result := Result + mn * Ord(s[i]);
    end;
  end;
end;

Посмотреть биты через строку

function ShowBits(a:byte):string; 
var i: Integer; 
begin 
 for i := 7 downto 0 do 
 // Variant1 
 if (a and (1 shl i))<>0 then Result:=Result+'1' else 
 Result:=Result+'0'; 
 // Variant2 
 //for i:=7 downto 7 do if ((a shr i) and 1)=1 then 
   Result:=Result+'1' 
   else 
   Result:=Result+'0'; 
end;
Continue reading
Posted in Без рубрики | Comments Off on Delphi. Некоторые функции для работы с битами

DesignPatterns. Composite

Для иерархических структур

client

program Composite;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  uComposer in 'uComposer.pas';

var
  l: TLetter;
  s: TSentence;

begin
  try
    l := TLetter.Create('!');
    s := TSentence.Create();
    try
      s.Sentence.Add(TLetter.Create('h'));
      s.Sentence.Add(TLetter.Create('e'));
      s.Sentence.Add(TLetter.Create('l'));
      s.Sentence.Add(TLetter.Create('l'));
      s.Sentence.Add(TLetter.Create('o'));

      s.Sentence.Add(TLetter.Create(' '));

      s.Sentence.Add(TLetter.Create('w'));
      s.Sentence.Add(TLetter.Create('o'));
      s.Sentence.Add(TLetter.Create('r'));
      s.Sentence.Add(TLetter.Create('l'));
      s.Sentence.Add(TLetter.Create('d'));

      s.Draw();
      l.Draw();

      Readln;
    finally
      l.Free();
      s.Free();
    end;

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Composite