Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Использование шаблона Visitor для обнаружения дубликатов в списке ObjectList в Delphi

Delphi , Синтаксис , Циклы

В статье рассматривается использование шаблона Visitor для обнаружения дубликатов в списке ObjectList в Delphi.

Шаблон Visitor представляет собой паттерн проектирования, который позволяет добавлять операции над объектами, не изменяя их структуру. В данном случае мы будем использовать его для обнаружения дубликатов в списке ObjectList.

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

Вот пример кода на Object Pascal, который демонстрирует, как это можно сделать:

type
  TMyObject = class
    Name: string;
    constructor Create(const AName: string);
  end;

  TObjectList = class
    FObjects: TArray<TMyObject>;
    procedure Add(const AObject: TMyObject);
    function Contains(const AObject: TMyObject): Boolean;
  end;

constructor TMyObject.Create(const AName: string);
begin
  Name := AName;
end;

procedure TObjectList.Add(const AObject: TMyObject);
begin
  SetLength(FObjects, Length(FObjects) + 1);
  FObjects[High(FObjects)] := AObject;
end;

function TObjectList.Contains(const AObject: TMyObject): Boolean;
var
  I: Integer;
begin
  Result := False;
  for I := 0 to High(FObjects) do
    if FObjects[I] = AObject then
    begin
      Result := True;
      Break;
    end;
end;

var
  List: TObjectList;
  Object1, Object2: TMyObject;
begin
  List := TObjectList.Create;
  try
    Object1 := TMyObject.Create('Object1');
    Object2 := TMyObject.Create('Object2');
    List.Add(Object1);
    List.Add(Object2);
    if List.Contains(Object1) then
      Writeln('Object1 is in the list');
    if List.Contains(Object2) then
      Writeln('Object2 is in the list');
  finally
    List.Free;
  end;

В данном примере мы создаем класс TMyObject, который представляет собой простой объект со строковым полем Name. Затем мы создаем класс TObjectList, который представляет собой список объектов TMyObject. В этом классе мы добавляем метод Add для добавления объектов в список и метод Contains для проверки наличия объекта в списке.

Далее, в основном коде, мы создаем экземпляр класса TObjectList и добавляем в него два объекта TMyObject. После этого мы проверяем наличие этих объектов в списке с помощью метода Contains.

Однако, данный подход имеет свои недостатки. Во-первых, он требует наличия метода Contains в классе TObjectList, что может привести к увеличению размеров кода. Во-вторых, данный подход не масштабируется на большие списки, так как для каждого элемента списка нам приходится проходить по всему списку в поисках дубликата.

Для решения этих проблем можно воспользоваться шаблоном Visitor. Суть шаблона заключается в том, чтобы добавить метод Visit в каждый класс, который мы хотим проверить на дубликаты. Этот метод будет вызываться для каждого объекта в списке, и в нем мы будем проверять, есть ли такой же объект в списке.

Вот пример кода, который демонстрирует, как это можно сделать:

type
  IVisitor = interface
    procedure Visit(const AObject: TMyObject);
  end;

  TMyObject = class
    Name: string;
    constructor Create(const AName: string);
    procedure Accept(IVisitor);
  end;

  TObjectList = class
    FObjects: TArray<TMyObject>;
    procedure Add(const AObject: TMyObject);
    procedure VisitAll(const IVisitor: IVisitor);
  end;

constructor TMyObject.Create(const AName: string);
begin
  Name := AName;
end;

procedure TMyObject.Accept(const IVisitor: IVisitor);
begin
  IVisitor.Visit(Self);
end;

procedure TObjectList.Add(const AObject: TMyObject);
begin
  SetLength(FObjects, Length(FObjects) + 1);
  FObjects[High(FObjects)] := AObject;
end;

procedure TObjectList.VisitAll(const IVisitor: IVisitor);
var
  I: Integer;
begin
  for I := 0 to High(FObjects) do
    FObjects[I].Accept(IVisitor);
end;

type
  TDuplicateVisitor = class(TInterfacedObject, IVisitor)
  private
    FDuplicates: TArray<TMyObject>;
  public
    constructor Create;
    procedure Visit(const AObject: TMyObject);
    function GetDuplicates: TArray<TMyObject>;
  end;

constructor TDuplicateVisitor.Create;
begin
  SetLength(FDuplicates, 0);
end;

procedure TDuplicateVisitor.Visit(const AObject: TMyObject);
var
  I: Integer;
begin
  for I := 0 to High(FDuplicates) do
    if FDuplicates[I] = AObject then
      Break;
  if I = High(FDuplicates) then
  begin
    SetLength(FDuplicates, Length(FDuplicates) + 1);
    FDuplicates[High(FDuplicates)] := AObject;
  end;
end;

function TDuplicateVisitor.GetDuplicates: TArray<TMyObject>;
begin
  Result := FDuplicates;
end;

var
  List: TObjectList;
  Visitor: TDuplicateVisitor;
begin
  List := TObjectList.Create;
  try
    Object1 := TMyObject.Create('Object1');
    Object2 := TMyObject.Create('Object2');
    List.Add(Object1);
    List.Add(Object2);
    Visitor := TDuplicateVisitor.Create;
    try
      List.VisitAll(Visitor);
      Writeln('Duplicates:');
      for var Duplicate in Visitor.GetDuplicates do
        Writeln(Duplicate.Name);
    finally
      Visitor.Free;
    end;
  finally
    List.Free;
  end;

В данном примере мы создаем интерфейс IVisitor, который будет использоваться для посещения каждого объекта в списке. Затем мы добавляем метод Accept в класс TMyObject, который будет вызываться для каждого объекта в списке и вызывать метод Visit интерфейса IVisitor.

Далее, мы создаем класс TDuplicateVisitor, который реализует интерфейс IVisitor и содержит список дубликатов. В методе Visit мы проверяем, есть ли такой же объект в списке дубликатов, и если нет, то добавляем его в список.

Наконец, в основном коде, мы создаем экземпляр класса TObjectList и добавляем в него два объекта TMyObject. После этого мы создаем экземпляр класса TDuplicateVisitor и передаем его в метод VisitAll класса TObjectList. В результате, в списке дубликатов окажутся все дубликаты из списка TObjectList.

Шаблон Visitor позволяет нам добавить операции над объектами, не изменяя их структуру, что делает код более гибким и легко расширяемым. В данном примере мы использовали его для обнаружения дубликатов в списке ObjectList в Delphi.

Создано по материалам из источника по ссылке.

В статье рассматривается использование шаблона Visitor для обнаружения дубликатов в списке ObjectList в Delphi.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Циклы ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-19 13:29:56
2024-11-21 11:35:06/0.0056569576263428/1