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

Delphi. UniGUI. Установка картинок в Grid

Делается это так, разными способами. Через Canvas, либо UniImage

procedure TMainForm.UniDBGrid1FieldImage(const Column: TUniDBGridColumn; const AField: TField; var OutImage: TGraphic; var DoNotDispose: Boolean; var ATransparent: TUniTransparentOption);
begin
  if SameText(AField.FieldName, 'Name2') then
  begin
    OutImage := TBitmap.Create;
    with (OutImage as TBitmap) do
    begin
      SetSize(128, 32);
      Canvas.Font.Size := 12;
      Canvas.Font.Color := clBlue;
      Canvas.Font.Style := [fsBold, fsItalic];
      Canvas.Brush.Style := bsBDiagonal;
      Canvas.Brush.Color := clGreen;
      Canvas.Rectangle(1, 1, 127, 31);
      Canvas.TextOut(2, 2, AField.DisplayText);
    end;
  end
  else if SameText(AField.FieldName, 'gender') then
  begin
    DoNotDispose := True; // we provide an static image so do not free it.
    if AField.AsString = 'male' then
      OutImage := UniImage1.Picture.Graphic
    else if AField.AsString = 'female' then
      OutImage := UniImage2.Picture.Graphic;
  end;
end;

Через Url

procedure TMainForm.UniDBGrid1FieldImageURL(const Column: TUniDBGridColumn; const AField: TField; var OutImageURL: string);
begin
  if (Column.Tag = 255) and SameText(AField.FieldName, 'shift') then
  begin
    if AField.AsBoolean then
      OutImageURL := 'files/sun.jpeg'
    else
      OutImageURL := 'files/moon.jpeg';
  end;
end;
Posted in Без рубрики | Comments Off on Delphi. UniGUI. Установка картинок в Grid

Delphi. Properties

Свойства (properties), как и поля, являются атрибутами объекта. Поле это хранилище данных, свойство же обеспечивает доступ к этому хранилищу через Read / Write.

Синтаксис свойства следующий

property propertyName[indexes]: type index integerConstant specifiers;

propertyName – валидное название

indexes – это последовательность деклараций, объявленных через точку с запятой, опционально

type тип должен быть предопределен

index – integer константа, опционально

specifiers – это ключевые слова, такие как readwritestoreddefault (or nodefault), implements. Также, по крайней мере одно из ключевых слов read / write должно быть объявлено.

Свойства не всегда обязательно существуют в памяти, и поэтому их нельзя передавать как var параметры или через @. Они могут иметь только ключевое слово read, которое добывает значение из базы данных или генерирует случайное значение.

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

Delphi. Mock FrameWork

Открыл для себя Mock FrameWork. Работает, начиная с XE2. Основное назначение – эмуляция тестовых случаев в юнит тестах, “а что будет с методом, если переменная будет такая, а другая?”

GitHub

Далее, я сделаю некоторый вольный перевод статьи с GitHub. Mock FrameWork поддерживает интерфейсы и классы. Интерфейс должен иметь RTTI информацию, на борту, для этого необходимо включить директиву {$M+}

Continue reading
Posted in Без рубрики | Comments Off on Delphi. Mock FrameWork

DesignPatterns. Bridge

Абстракция и имплементация могут развиваться отдельно. В нужный момент мы их связываем.

Пример из жизни – GUI и BackEnd. Могут развиваться отдельно, но в определенный момент мы их связываем.

Канонический пример. Пусть есть некоторый метод Operatoin в абстракции и имплементации. Этот метод и будет являться связью.

program Bridge;

{$APPTYPE CONSOLE}

{$R *.res}

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

var
  a: TAbstraction;
  i: TImplementor;

begin
  i := TConcreteImplementor();
  a := TRefinedAbstraction.Create(i); // связали абстракцию и имплементацию
  try
    a.Implementor.Operation();
  finally
    i.Free();
    a.Free();
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Bridge

DesignPatterns. Adapter

Для связи интерфейсов, простой пример

program Adapter;

{$APPTYPE CONSOLE}

{$R *.res}

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

var
  englishSpeakingRussian: TRussianToEnglishAdapter;

begin
  try
    englishSpeakingRussian := TRussianToEnglishAdapter.Create();
    try
      Writeln(englishSpeakingRussian.SayHello());
      ReadLn;
    finally
      englishSpeakingRussian.Free();
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Continue reading
Posted in Без рубрики | Comments Off on DesignPatterns. Adapter