Конференция "Основная" » Реализация интерфейса-мастера.
 
  • oxffff © (04.03.08 08:38) [20]

    > Вот как это делать ты прелагаешь — непонятно.


    function TStepNode.Back:boolean;
    begin
    BeforeMoveBack;
    result:=controller.back(self);
    AfterMoveBack(result);
    end;

    procedureTStepController.back(node:TStepNode);
    begin
    if AllowBack and node.AllowBack  then     // paranoiac AllowBack :)
     begin
     Node.Detach;   // on Node
     setStepNode(previous); // <- где previous может быть не предыдущий,
                                     а тот например который Skipped, либо другое    поведение на твое усмотре
     previous.Attach;
     end;
    end;

    Что еще не понятно?
  • Kolan © (04.03.08 08:40) [21]
    То есть ты предлагаешь логику работы из контроллера распылить по всем окнам, так?
  • Kolan © (04.03.08 08:42) [22]
    И вообще непонятно как в этом случае ты на шаге 2 что-то запомнишь, а на шаге 4 что-то с этим сделаешь, если формы ничего не знают про друг друга…
  • KSergey © (04.03.08 08:46) [23]
    как обычно - сценарий меняется по ходу пьессы.
    Это уже не интересно становится. Неужели нельзя все сразу было рассказать?

    По поводу "переменных на разных шагах" - ну так это для пользователя эти шаги - разные. Но что мешает все состояние хранить в одном месте, в общей куче от всех "шагов"? По сути ведь есть некий объект (здесь обьек - условность, не в смысле ООП), управление которым исключительно для удобства (не более!) разнесено на несколько "шагов" вместо одного огромного экрана.
    По-моему, именно так стоит на это все смотреть. Т.е. экраны шагов - друг про друга пусть не знают, однако меняют состояние одного общего объекта (опять же не буквально в терминах ООП). Может и не экраны меняют его состояние, а из них просто информация вычитывается. Тут смотреть надо как связей меньше.
  • Kolan © (04.03.08 09:02) [24]
    > как обычно — сценарий меняется по ходу пьессы.

    «Допустим есть 4 шага. На шаге 2 пользователь вводит данные, а на шаге 4 их надо обработать как-то.» © [0] Kolan


    > Может и не экраны меняют его состояние, а из них просто
    > информация вычитывается.

    Вот тут я и прошу конкретный пример, бо всплывают проблеммы… Все написанное я понимаю.
  • oxffff © (04.03.08 09:02) [25]

    > Kolan ©   (04.03.08 08:42) [22]
    > И вообще непонятно как в этом случае ты на шаге 2 что-то
    > запомнишь, а на шаге 4 что-то с этим сделаешь, если формы
    > ничего не знают про друг друга…


    А что мешает тебе определить шаги в одном модуле например и использовать shared переменные.
    Либо при создании их ссылаться друг на друга.
    Либо и т.д.

    Если шаги взаимодействуют они это делают согласно контракта.
    Какой контракт это выбор за тобой.
  • oxffff © (04.03.08 09:07) [26]

    > моему, именно так стоит на это все смотреть. Т.е. экраны
    > шагов - друг про друга пусть не знают, однако меняют состояние
    > одного общего объекта (опять же не буквально в терминах
    > ООП). Может и не экраны меняют его состояние, а из них просто
    > информация вычитывается. Тут смотреть надо как связей меньше.
    >


    Это и есть контракт. Но это все разновидность [25].
  • Kolan © (04.03.08 09:10) [27]
    > Либо и т.д.

    Либо, либо, вариантов масса… а конкретного примера тен.

    Ладно шас выложу свой вариант, будите ругать :).
  • Kolan © (04.03.08 10:38) [28]
    Вроде получилось неплохо:

    Есделал такого предка:

     TCustomTouchForm = class(TForm)
     private
       FWindowCode: string;
       FControllerInterface: IControllerInterface;
       FOtherInterfacesObjetc: TObject;
     protected
       function GetControllerInterface: IControllerInterface;
     public
       {С помощью этой операции можно узнать поддерживает или нет форма код.
        Таких кодов может быть несколько.}

       class function SupportsWindowCode(AWindowCode: string): Boolean; virtual; abstract;

       {При создании формы ей указывают конкретный её код.
        Если поддерживать форма может несколько кодов, то создается с конкретным.
        А с каким именно знает тот, кто её создает.}

       constructor Create(AWindowCode: string;
         AControllerInterface: IControllerInterface;
         AOtherInterfacesObjetc: TObject); reintroduce;
       property WindowCode: string read FWindowCode write FWindowCode;
     end;

     TCustomTouchFormClass = class of TCustomTouchForm;



    Контроллер такой:

    procedure TSystemController.Act(ASenderWindowCode,
     APerformedActionName: string);
    begin
     if ASenderWindowCode = 'Start' then
     begin
       ShowWindow('0.0');
     end;                

     if ASenderWindowCode = '0.0' then
     begin
       if APerformedActionName = 'Settings' then
         ShowWindow('7.0');
     end;

     if ASenderWindowCode = '7.0' then
     begin
       if APerformedActionName = 'Back' then
         ShowWindow('0.0');    
     end;
     
    end;



    Вот показ формы:
    procedure TSystemController.ShowWindow(AWindowCode: string);
    var
     TouchForm: TCustomTouchForm;
    begin
     TouchForm := GetWindowsFactory.GetWindow(AWindowCode, Self, nil);
     if Assigned(TouchForm) then
     begin
       TouchForm.Show;
       TouchForm.FormStyle := fsStayOnTop;
     end
     else
       raise EFormNotFoundException.Create(AWindowCode);
    end;



    Каждая форма регистрирует совй класс в фабрике:
    initialization
     GetWindowsFactory.AttachTouchFormClass(TSettingsForm);



    Фабрика создает окна так:

    function TWindowsFactory.GetWindow(AWindowCode: string;
     AControllerInterface: IControllerInterface;
     AOtherInterfacesObject: TObject): TCustomTouchForm;
    begin
     Result := nil;
     {Найи форму в кэше.}
     Result := FFormsList.FindForm(AWindowCode);
     if Assigned(Result) then
     begin
       FFormsList.DeleteAllFormsAfterGiven(Result);
     end
     else
     begin
       {Если форма не найдена, то создать её.}
       Result := CreateWindow(AWindowCode, AControllerInterface, AOtherInterfacesObject);
       if Assigned(Result) then
         FFormsList.Add(Result);
     end;
    end;



    А еще на каждой форме лежит экше лист в OnExecute которого написано:
    procedure TSettingsForm.MainActionListExecute(Action: TBasicAction;
     var Handled: Boolean);
    begin
     GetControllerInterface.Act(WindowCode, Action.Name);
    end;



    Как бы сделать так, чтобы у предка всех форм это экшен лист сразу бы лежал на форме?

    Хоть и кейс но все в одном месте вроде…
  • Kolan © (04.03.08 10:45) [29]
    К когду контроллера прилагается State Chart…
  • KSergey © (04.03.08 11:30) [30]
    Зачем люди переносят заморочки, требуемые в С++ в дельфийский код? В дельфи можно и без всякие рукописных прибабахнутых фабрик объекты по указанному классу создавать, все для этого в компиляторе уже есть. Зачем отсебятину придумывать? Да и все сознаддые формы в Screen.Forms уже есть. Хотя, конечно, иногда бывает проще свой список поддерживать, только для требуемых форм, но тоже вопрос еще.

    А использовать по тексту строковые константы - ваще капец. Описка в букве - и превед отладчег. Можно ведь и просто константами все описать, причем - перчислением, как и было сказано. Они - integer, их проверять быстрее у процессора выходит, да и описки - компилятором все отловятся.

    В общем на мой вкус - много лишних сущностей. Но это наверняка субъективно.
  • Kolan © (04.03.08 11:56) [31]
    > Зачем люди переносят заморочки, требуемые в С++

    Я его с трудм читаю…

    > указанному классу создавать

    А кто укажет его?


    > А использовать по тексту строковые константы — ваще капец.

    Ладно, а где их хранить, приведи пример…
  • KSergey © (04.03.08 12:17) [32]
    > Kolan ©   (04.03.08 11:56) [31]
    > > указанному классу создавать
    > А кто укажет его?

    Тот же контроллер, но сразу нужный класс формы шага. И все. Никаких рукописных фабрик классов не надо.

    > Kolan ©   (04.03.08 11:56) [31]
    > Ладно, а где их хранить, приведи пример…

    А чем [1] не нравится?
  • Kolan © (04.03.08 12:37) [33]
    > А чем [1] не нравится?

    Я не поняимаю как конкретно рпелагается это решнение использовать, как инстанцировать и убивать формы…
  • KSergey © (04.03.08 12:44) [34]
    > Kolan ©   (04.03.08 12:37) [33]
    >  как инстанцировать и убивать формы…

    http://www.delphikingdom.com/asp/viewitem.asp?catalogid=342
    раздел "Лень, как источник вдохновения."
  • Kolan © (04.03.08 12:50) [35]
    > [34] KSergey ©   (04.03.08 12:44)

    Ты че издеваешься что ли? Ты думаешь я незнаю как создать форму что ли? Ты покажи напримере как ты сделаешь с состояниями, я же мысли не читаю.

    «Используй перечисление» — это что, то что их как-то можно использовать я понимаю и так? Тут же вопрос именно как все организовать…
  • Kolan © (04.03.08 12:54) [36]
    А делать такую хрень:
    ListClass : TListClass  = (TEdit , TButton , TCheckBox , TLabel ) ;

    Длинну которой придется кажды раз руками менять, и в которую еще надо будет вручную добавлять компоненты я нехочу. Я сделал тоже самое, но более автоматизировано.

    Каждая форма регистрирует совй класс в фабрике:
    initialization
    GetWindowsFactory.AttachTouchFormClass(TSettingsForm);



    А вот создание:
    function TWindowsFactory.CreateWindow(AWindowCode: string;
     AControllerInterface: IControllerInterface;
     AOtherInterfacesObjetc: TObject): TCustomTouchForm;
    var
     FormClass: TCustomTouchFormClass;
    begin
     Result := nil;
     FormClass := FFormsClasses.FindFormClass(AWindowCode);
     if FormClass <> nil then
       Result := FormClass.Create(AWindowCode, AControllerInterface, AOtherInterfacesObjetc);
    end;

  • oxffff © (04.03.08 14:05) [37]

    > Kolan ©   (04.03.08 12:54) [36]
    > А делать такую хрень:
    > ListClass : TListClass  = (TEdit , TButton , TCheckBox ,
    >  TLabel ) ;


    А у тебя тоже все статично. Захочешь добавить будешь править свой

    procedure TSystemController.Act(ASenderWindowCode,
    APerformedActionName: string);
    begin
    if ASenderWindowCode = 'Start' then
    begin
      ShowWindow('0.0');
    end;                

    if ASenderWindowCode = '0.0' then
    begin
      if APerformedActionName = 'Settings' then
        ShowWindow('7.0');
    end;

    if ASenderWindowCode = '7.0' then
    begin
      if APerformedActionName = 'Back' then
        ShowWindow('0.0');    
    end;

    end;
  • Kolan © (04.03.08 14:17) [38]
    > А у тебя тоже все статично. Захочешь добавить будешь править
    > свой

    Ну а как без этого, хоть ListClass не править. Этим мне и ненравится кейс… О чем собссно и вся ветка с самого начала…
  • oxffff © (04.03.08 14:48) [39]

    > Kolan ©   (04.03.08 14:17) [38]


    Перечитай сначала. :)
 
Конференция "Основная" » Реализация интерфейса-мастера.
Есть новые Нет новых   [134483   +44][b:0][p:0.003]