Recent

Author Topic: Best way to exchange data between a form and a unit  (Read 36181 times)

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Best way to exchange data between a form and a unit
« on: January 10, 2024, 05:31:18 pm »
What is the best way to exchange data between a form and a unit. Include the form in the uses of the unit or work with (many) properties in the unit?
Or is there a better way?

cdbc

  • Hero Member
  • *****
  • Posts: 1247
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #1 on: January 10, 2024, 06:02:54 pm »
Hi
That depends entirely on, how tight a dependency, you wish to have...  ::)
- tight: list the form-unit in the implementation-part(if form uses other unit) of
  the other unit, else in interface-part. By & Far the easiest way.
- loose: use shared libraries, interfaces, files(?!?) & functions and callbacks...
  I tend to use interfaces  8)

edit: here's a good book for you then: https://pdfcoffee.com/mvvm-in-delphi-pdf-free.html
edit2: and the source on github: https://github.com/Apress/mvvm-in-delphi

It all seems legal enough...?!?
Regards Benny
« Last Edit: January 10, 2024, 07:40:38 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Re: Best way to exchange data between a form and a unit
« Reply #2 on: January 10, 2024, 07:08:21 pm »
Quote
- tight: list the form-unit in the implementation-part(if form uses other unit) of
  the other unit, else in interface-part. By & Far the easiest way.
That's how I always did it, but that's not the best way if I read it carefully in various articles. I would like to learn how to start decoupling the form from the units with the logic.

TRon

  • Hero Member
  • *****
  • Posts: 2801
Re: Best way to exchange data between a form and a unit
« Reply #3 on: January 10, 2024, 07:15:18 pm »
That's how I always did it, but that's not the best way if I read it carefully in various articles. I would like to learn how to start decoupling the form from the units with the logic.
It depends on what you consider the best way. If projects become larger then it is unmaintainable and often better to completely separate the two.

In such cases you are better off by keeping form related code to your form and create a separate unit for your data storage. Whether or not you want to process the data in that same data unit is also up for debate. I often use a separate data storage unit which doesn't operate on the data itself (in which case another unit is used for actual data processing) . Now with newer constructs such as advanced records and generics this becomes more often a choice which you would have to consider.
« Last Edit: January 10, 2024, 07:16:59 pm by TRon »

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Re: Best way to exchange data between a form and a unit
« Reply #4 on: January 10, 2024, 08:08:26 pm »
I believe I have my first useful case for chatgpt. With reference to chatgpt I now have a simple example that uses the mvp pattern. (1 TForm with 1 TButton and 1 TEdit). The answer was without errors. Now I just have to understand it.

I will take a look at the book. (got the pdf file).


cdbc

  • Hero Member
  • *****
  • Posts: 1247
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #5 on: January 10, 2024, 09:07:35 pm »
Hi
Your project is missing 3 key lines of code:
Code: Pascal  [Select][+][-]
  1. ...
  2.   public
  3.     constructor Create(Model: IModel; View: TForm; Button: TButton; Edit: TEdit);
  4.     destructor Destroy; override; // <--- ADD THIS
  5.   end;
  6. implementation
  7.  
  8. constructor TPresenter.Create(Model: IModel; View: TForm; Button: TButton; Edit: TEdit);
  9. begin
  10.   FModel := Model;
  11.   FView := View;
  12.   FButton := Button;
  13.   FEdit := Edit;
  14.   FModel.Attach(FButton); // <--- ADD THIS LINE
  15.   FButton.OnClick := @ButtonClick;
  16.   FEdit.OnChange := @TextChanged;
  17. end;
  18.  
  19. destructor TPresenter.Destroy; // ADD THIS METHOD
  20. begin
  21.   FModel.Detach(FButton); // <--- important to avoid av's on shutdown
  22.   inherited Destroy;
  23. end;                    
  24.  
Happy coding, you're on the right track  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Re: Best way to exchange data between a form and a unit
« Reply #6 on: January 12, 2024, 06:30:16 pm »
Quote
constructor TPresenter.Create(Model: IModel; View: TForm; Button: TButton; Edit: TEdit);

What if there are many buttons and edit and other components? Then the create procedure becomes very long. Or do you create multiple instances of the presenter? Or multiple constructors?


If there are multiple buttons, how do you know which is the right one? And what if there are other components besides buttons?
Code: Pascal  [Select][+][-]
  1. procedure TModel.Notify;
  2. var
  3.   i: Integer;
  4. begin
  5.   for i := 0 to FObservers.Count - 1 do
  6.     TButton(FObservers[i]).Caption := FText;
  7. end;  


Thaddy

  • Hero Member
  • *****
  • Posts: 14849
  • Censorship about opinions does not belong here.
Re: Best way to exchange data between a form and a unit
« Reply #7 on: January 12, 2024, 06:47:16 pm »
If there are multiple buttons, how do you know which is the right one? And what if there are other components besides buttons?
if, is, as and sender. But observed components are registered to be observers. As long as you use the observer pattern as provided as standard for components. Or do you use your own observer/observed?
« Last Edit: January 12, 2024, 06:52:41 pm by Thaddy »
Remember the Medway disaster..

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Re: Best way to exchange data between a form and a unit
« Reply #8 on: January 12, 2024, 08:28:36 pm »
I save everything in a TList.
Code: Pascal  [Select][+][-]
  1. FObservers: TList;

Just standard stuff as far as I know.





cdbc

  • Hero Member
  • *****
  • Posts: 1247
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #9 on: January 12, 2024, 09:52:29 pm »
Hi
@Hansvb: Your uploaded example, /is/ a /very/ simple example, on which you can't really build something serious.
1) Take a look, at how the observer pattern is implemented in "TPersistent" and hence present in all lcl-components as a "Subject" to observe. You literally have to write 3 lines of code in a class, to be able to observe any component you like  8-)
2) Read the book, it also provides a simplified example, but _way_ better than your first one. If need be, I have ported it to lazarus, could make it available to you.
3) Basically you have 3 objects/components that work together:
3,1) Model ~ your data-layer (database, textfiles, web-requests, etc)
3,2) Presenter ~ your controller, sits in the middle and controls communication and data access + it provides the view/form(s) with data when they ask for them, typically via the observer pattern.
3,3) View ~ what the user sees and touches, (as dumb as you can make it), it sends user actions to the presenter, which talks to/with the model and fetches data, makes them pretty and sends them through the "Observed/Subject" to the attached view(s), so the user can see them.
Of course there's a learning curve, but it's not too steap  :D
...And when you get used to "Compartementalizing" it makes a lot of tasks easier...
HTH
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Re: Best way to exchange data between a form and a unit
« Reply #10 on: January 13, 2024, 12:06:28 pm »
I still have to read Delphi mvvm. I want to print first because it's easier for me to read from paper.

Made a new try. This can handle multiple buttons and checkboxes. This is more useful for me then the first attempt. But it is stil not good. (or at least i do not understand exact what happens).

cdbc, what do you think of this?

Thaddy

  • Hero Member
  • *****
  • Posts: 14849
  • Censorship about opinions does not belong here.
Re: Best way to exchange data between a form and a unit
« Reply #11 on: January 13, 2024, 03:18:31 pm »
https://forum.lazarus.freepascal.org/index.php/topic,56872.msg422686.html#msg422686

Contrary to his memory I know who wrote it: Sven/Sarah

This is an example of the built-in Observer pattern and you should use that.
Remember the Medway disaster..

cdbc

  • Hero Member
  • *****
  • Posts: 1247
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #12 on: January 13, 2024, 04:45:16 pm »
Hi
@Hansvb: Sorry mate, i'ld rather not put in writing, what I think about it  :-X
You can do better! Look at the examples @Thaddy mentioned.
Btw. Kudos to Sven/Sarah a.k.a. PascalDragon, for writing this sleek and elegant code in the RTL  :)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Thaddy

  • Hero Member
  • *****
  • Posts: 14849
  • Censorship about opinions does not belong here.
Re: Best way to exchange data between a form and a unit
« Reply #13 on: January 13, 2024, 05:27:01 pm »
On implementing mvp or mvvp there are actually multiple entities.
1 The logic goes in 1 unit, without references to any GUI relationship
2 The GUI parts use that unit and just implement that unit (or units).

It should be so decoupled that it should not matter if you use the logic in a console application or GUI app.
Remember the Medway disaster..

Hansvb

  • Hero Member
  • *****
  • Posts: 631
Re: Best way to exchange data between a form and a unit
« Reply #14 on: January 13, 2024, 06:56:49 pm »
Is there a good book that explains this? I find too many examples with Google that don't look alike. And it seems that they only assume the simplest scenario.

I can't even figure out how to convert the example
Quote
https://forum.lazarus.freepascal.org/index.php/topic,56872.msg422686.html#msg422686
to an edit.


 

TinyPortal © 2005-2018