Элегантная замена IF ... THEN

Рейтинг: 2Ответов: 1Опубликовано: 16.08.2023

Есть большой список объектов, над каждым объектом пользователь может выполнять разные действия.

  1. Объект А - может читать, удалять, редактировать

  2. Объект Б - может читать, редактировать

  3. Объект С - только просмотр.

и т.д. На форме есть кнопки, которые должны активироваться в зависимости от прав на данный объект.

  // Класс объекта
  TBuilding = class(TRootClass)
  private
    ....
    // Object Accesses
    FCanRead: boolean;
    FCanEdit: boolean;
    FCanDelete: boolean;
    function GetCanDelete: boolean;
    function GetCanEdit: boolean;
    function GetCanRead: boolean;
  public
    ....
    property CanRead: boolean read GetCanRead;
    property CanEdit: boolean read GetCanEdit;
    property CanDelete: boolean read GetCanDelete;

Собственно, вместо IF ... THEN приходит на ум реализация примерно следующего

...
 procedure TObjectViewer.StringGrid1CellClick(const Column: TColumn;
  const Row: Integer);
 begin
    // DoSomething
     BEditObject.Enabled := Building.CanEdit;
     BtnDeleteObject.Enabled := Building.CanDelete;
 end;
...

В данном примере прав достаточно мало, однако есть другие сущности в которых их в 3 а то и 4 раза больше. Как вы бы подошли к решению данного вопроса?

Ответы

▲ 2Принят

У всех контролов в Delphi есть свойство Tag, можно воспользоваться им.

  1. Создаёте перечислимый тип, содержащий все возможные разрешения, с явно заданными числовыми значениями отличными от нуля, например, type TRight = (canRead = 1, canEdit = 2, …);

  2. У объекта создаёте метод, возвращающий булево значение разрешению, например, function CanDo(ARight: TRight): Boolean;. Можно заменить на свойство-массив.

  3. Всем кнопкам задаёте значение поля Tag равным соответствующему разрешению.

  4. В цикле перебираете все контролы формы/панели, если тэг не 0, то присваиваете его свойству Enabled значение функции CanDo:

for i := 0 to MyForm.ControlCount - 1 do
  if MyForm.Controld[i].Tag > 0 then
    MyForm.Controld[i].Enadbled := Building.CanDo(TRight(MyForm.Controld[i].Tag));