![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как дисэйблить кнопки если операция не поддерживается… ?
Kolan © (2008-01-25 15:32:00)Здравствуйте,
Допустим у нас есть два вида объектов А и Б.
С ними можно выполнять похожие по смыслы(интерфейсу) операции, только реализованы они будут по разному.
Понятно, что удобно узать стратегии. Тогда надо определить общий интерфейс, и сделать его конкретный реализации для А и Б.
Пример:
IItemsOperationsController = interface
['{3574BBB8-1413-4508-AD48-F4BEFFC88A28}']
procedure AddItem;
procedure DeleteCurrentItem;
procedure SetCurrentItem(AnObject: TObject);
procedure PerformOpertionWithCurretnItem(ADeviceOperationPerformer:
IDeviceOperationPerformer);
end;
TCustomItemsOperationsController = class(TInterfacedObject, IItemsOperationsController)
public
procedure AddItem; virtual; abstract;
procedure DeleteCurrentItem; virtual; abstract;
procedure SetCurrentItem(AnObject: TObject); virtual; abstract;
procedure PerformOpertionWithCurretnItem(ADeviceOperationPerformer:
IDeviceOperationPerformer); virtual; abstract;
end;
TNetItemsOperationsController = class(TCustomItemsOperationsController)
protected
function QueryNetName(var AName: string): Boolean;
public
procedure AddItem; override;
procedure DeleteCurrentItem; override;
procedure SetCurrentItem(AnObject: TObject); override;
procedure PerformOpertionWithCurretnItem(ADeviceOperationPerformer:
IDeviceOperationPerformer); override;
end;
TDeviceItemsOperationsController = class(TCustomItemsOperationsController)
protected
function QueryDeviceAddress(var AnAddress: Byte): Boolean;
public
procedure AddItem; override;
procedure DeleteCurrentItem; override;
procedure SetCurrentItem(AnObject: TObject); override;
procedure PerformOpertionWithCurretnItem(ADeviceOperationPerformer:
IDeviceOperationPerformer); override;
end;
Тогда вызов будет такой(это код экшена):
procedure TMainForm.DeleteItemExecute(Sender: TObject);
begin
GetConfigurationUtilityController.DeleteCurrentItem;
end;
ГдеGetConfigurationUtilityController это синглетон, который делегирует вызов нужному контроллеру.
procedure TConfigurationUtilityController.DeleteCurrentItem;
begin
GetItemsOperationsController.DeleteCurrentItem;
end;
Но вот проблемма, объекты типа Б не поддерживают операцию удаления(например). Для них хорошо бы кнопочку(экшен) удалить сделать недоступной.
Вопрос: Как?
Kolan (2008-01-25 16:37:00) [21]> function OpsVisitor( )
Kolan (2008-01-25 16:34:00) [22]> А именно либо отдельный интерфейс
Паладин так и предлагает.
> Аля command согласно GOF
Возится с каждой командой долго выходит
offff (2008-01-25 16:34:00) [23]Удалено модератором
Примечание: дубль
offff (2008-01-25 16:34:00) [24]Либо сделать посетителя операций. и сделать посетителя Menu Manager.
IItemsOperationsController = interface
function OpsVisitor(...) <- сюда твоего Menu Manager
{
}
end
offff (2008-01-25 16:27:00) [25]
> Но вот проблемма, объекты типа Б не поддерживают операцию
> удаления(например). Для них хорошо бы кнопочку(экшен) удалить
> сделать недоступной.
Замечания к реализации. IMHO
Тогда и интерфейс IItemsOperationsController не должен ее содержать.
Добиться можно выделив операцию в отдельную сущность.
А именно либо отдельный интерфейс, либо класс на каждую операцию.
Аля command согласно GOF.
offff (2008-01-25 16:27:00) [26]Удалено модератором
Примечание: дубль
Palladin (2008-01-25 16:22:00) [27]
> procedure TMainForm.DeleteItemUpdate(Sender: TObject);
> begin
> (Sender as TAction).Enabled := GetConfigurationUtilityController.GetItemsOperationsController.GetInterface(IIte
> msOperationsControllerWithDeleteSupport, Int);
> end;
да, именно так
clickmaker (2008-01-25 16:19:00) [28]
> [7] Kolan © (25.01.08 16:16)
ну я тогда не понял твою задумку...
мне как-то старый добрый полиморфизм ближе в этом отношении
Kolan (2008-01-25 16:16:00) [29]> а переопределять ниже по иерархии
Непонял.
Как в [5] по идее не надо будет ничего перопределять
ЗЫ
Я же поэтому и прошу примерчик, а то непонятно
clickmaker (2008-01-25 16:05:00) [30]
> [5] Kolan © (25.01.08 15:57)
что-то у тебя мудренно как-то всё...
наверно, в IItemsOperationsController и объявить
а переопределять ниже по иерархии
Kolan (2008-01-25 15:57:00) [31]> IsSupported(operationName): boolean; virtual
Ну у кого это операция будет реализована?
В данном примере в Синглетоне (GetConfigurationUtilityController — это синглетон, который делегирует вызов нужному контроллеру.)?
Что-то вроде:
procedure TMainForm.DeleteItemUpdate(Sender: TObject);
begin
(Sender as TAction).Enabled := GetConfigurationUtilityController.GetItemsOperationsController.GetInterface(IIte msOperationsControllerWithDeleteSupport, Int);
end;
?
clickmaker (2008-01-25 15:53:00) [32]IsSupported(operationName): boolean; virtual
а вызывать в Action.OnUpdate
так, что-ли?
Kolan (2008-01-25 15:47:00) [33]> и фсе теперь можно определять поддержку удаления поддержкой
> интерфейса
Я примерно понял. Только ты, плз пример напиши
Нопонятно кто должен проверять поддержку и дисейблить
Palladin (2008-01-25 15:39:00) [34]ой, в базе обшибся, там Delete не нужен
Palladin (2008-01-25 15:38:00) [35]определяем базовый интерфейс
IItemsOperationsController = interface
procedure AddItem;
procedure DeleteCurrentItem;
procedure SetCurrentItem(AnObject: TObject);
procedure PerformOpertionWithCurretnItem(ADeviceOperationPerformer:
IDeviceOperationPerformer);
end;
определяем интерфейс наследник с поддержкой удаления
IItemsOperationsControllerWithDeleteSupport = interface(IItemsOperationsController)
procedure DeleteCurrentItem;
end;
и фсе... теперь можно определять поддержку удаления поддержкой интерфейса