-
Здравствуйте,
Допустим у нас есть два вида объектов А и Б.
С ними можно выполнять похожие по смыслы(интерфейсу) операции, только реализованы они будут по разному.
Понятно, что удобно узать стратегии. Тогда надо определить общий интерфейс, и сделать его конкретный реализации для А и Б.
Пример: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;
Но вот проблемма, объекты типа Б не поддерживают операцию удаления(например). Для них хорошо бы кнопочку(экшен) удалить сделать недоступной.
Вопрос: Как? -
Palladin © (25.01.08 15:38) [1]определяем базовый интерфейс
IItemsOperationsController = interface
procedure AddItem;
procedure DeleteCurrentItem;
procedure SetCurrentItem(AnObject: TObject);
procedure PerformOpertionWithCurretnItem(ADeviceOperationPerformer:
IDeviceOperationPerformer);
end;
определяем интерфейс наследник с поддержкой удаления
IItemsOperationsControllerWithDeleteSupport = interface(IItemsOperationsController)
procedure DeleteCurrentItem;
end;
и фсе... теперь можно определять поддержку удаления поддержкой интерфейса -
Palladin © (25.01.08 15:39) [2]ой, в базе обшибся, там Delete не нужен
-
> и фсе теперь можно определять поддержку удаления поддержкой
> интерфейса
Я примерно понял. Только ты, плз пример напиши
Нопонятно кто должен проверять поддержку и дисейблить -
clickmaker © (25.01.08 15:53) [4]IsSupported(operationName): boolean; virtual
а вызывать в Action.OnUpdate
так, что-ли? -
> IsSupported(operationName): boolean; virtual
Ну у кого это операция будет реализована?
В данном примере в Синглетоне (GetConfigurationUtilityController — это синглетон, который делегирует вызов нужному контроллеру.)?
Что-то вроде:procedure TMainForm.DeleteItemUpdate(Sender: TObject);
begin
(Sender as TAction).Enabled := GetConfigurationUtilityController.GetItemsOperationsController.GetInterface(IIte msOperationsControllerWithDeleteSupport, Int);
end;
? -
clickmaker © (25.01.08 16:05) [6]
> [5] Kolan © (25.01.08 15:57)
что-то у тебя мудренно как-то всё...
наверно, в IItemsOperationsController и объявить
а переопределять ниже по иерархии -
> а переопределять ниже по иерархии
Непонял.
Как в [5] по идее не надо будет ничего перопределять
ЗЫ
Я же поэтому и прошу примерчик, а то непонятно -
clickmaker © (25.01.08 16:19) [8]
> [7] Kolan © (25.01.08 16:16)
ну я тогда не понял твою задумку...
мне как-то старый добрый полиморфизм ближе в этом отношении -
Palladin © (25.01.08 16:22) [9]
> procedure TMainForm.DeleteItemUpdate(Sender: TObject);
> begin
> (Sender as TAction).Enabled := GetConfigurationUtilityController.GetItemsOperationsController.GetInterface(IIte
> msOperationsControllerWithDeleteSupport, Int);
> end;
да, именно так -
offff (25.01.08 16:27) [10]
> Но вот проблемма, объекты типа Б не поддерживают операцию
> удаления(например). Для них хорошо бы кнопочку(экшен) удалить
> сделать недоступной.
Замечания к реализации. IMHO
Тогда и интерфейс IItemsOperationsController не должен ее содержать.
Добиться можно выделив операцию в отдельную сущность.
А именно либо отдельный интерфейс, либо класс на каждую операцию.
Аля command согласно GOF. -
offff (25.01.08 16:27) [11]Удалено модератором
Примечание: дубль -
offff (25.01.08 16:34) [12]Либо сделать посетителя операций. и сделать посетителя Menu Manager.
IItemsOperationsController = interface
function OpsVisitor(...) <- сюда твоего Menu Manager
{
}
end -
offff (25.01.08 16:34) [13]Удалено модератором
Примечание: дубль -
> А именно либо отдельный интерфейс
Паладин так и предлагает.
> Аля command согласно GOF
Возится с каждой командой долго выходит -
> function OpsVisitor( ) < сюда твоего Menu Manager
Ну и что я буду говорить этому менеджеру? Задисейбли кнопку «Удалить». А если кнопок много? Что же их все пересчислять?
Паладин действительно прав. Получается я контракт нарущил. Говорю что оддерживаю удаление, а на самом деле нет Осталось грамотно связать -
offff (25.01.08 16:42) [16]
> Kolan © (25.01.08 16:37) [15]
Menu Manager - отключает все кнопки.
MenuManager=class(CommandVisitor)
procedure OpAdd
procedure OpRemove
Procedure OpCurrent
end;
Реализатор IItemsOperationsController пробегает по всем его коммандам и делает вызов
AbstractCommand.Accept(visitor:CommandVisitor)
procedure MenuManager.OpAdd
begin
ADDITEM.VISIBLE:=TRUE;
end;
procedure MenuManager.OpRemove
begin
RemoveITEM.VISIBLE:=TRUE;
end;
Procedure MenuManager.OpCurrent
begin
....
end; -
offff (25.01.08 16:42) [17]Удалено модератором
Примечание: да что'ж ты дублями то :) -
Что то задублилось у меня. Sorry.
Что касаемо реализации то я уже тут предлагал улучшенную реализацию GOF паттерна VISITOR без привязки к VMT.
Кстати напишу в своем блоге об этом.
:) -
> offff (25.01.08 16:42) [17]
> Удалено модератором
> Примечание: да что'ж ты дублями то :)
Sorry снова. Сам не знаю что за дела. Под oxffff пользователем порядок.
:)