Recent

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

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2269
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Best way to exchange data between a form and a unit
« Reply #45 on: January 20, 2024, 11:26:07 pm »
I will try to create the directory creater tomorrow.

What else comes to mind. Won't the presenter and the model be way too big if everything goes into it? Or can you have multiple models talk to 1 presenter? Normally, I try to separate things into different units.
Since methods should be fully decoupled in such a code environment, you can/should have your actual methods outside.
To me the presenter is like a window message handler that compute and react to a given task/message.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

cdbc

  • Hero Member
  • *****
  • Posts: 2522
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #46 on: January 21, 2024, 08:45:05 am »
Hi
Well, here's a bit of theory, the pattern as such is quite old, from the 80's SmallTalk etc. languages. It started life as MVC (M)odel (V)iew (C)ontroller, where the view showed the state data was in, as it best could and /any/ user actions went directly to the controller, which took /no/ part in showing anything. The model was/is the data/logic centric part, it knows how to gather, manipulate and produce data within its field of expertise.

The view often got its data directly from the model, via direct calls(polling) or an event-mechanism, later observer. The controller also talked directly to the model and these tight couplings slowly became problematic with complexity.

To extend the model, the term (B)usiness (O)bjects (M)odel, was coined to describe more models working under the same roof as _one_ entity, i.e.: you could have more functions / abilities / data working as one whole. To the outside world, it seems there's only 1 (now shortened to model) BOM.

A) Yes you can/should have your model in more units, the more complex it
    gets, the more the model exposes objects not functions in its API.

Now, (U)ser (I)nterfaces are notoriously hard, -to design right, -get to work just right and -test. It's completely opposite with the (P)resenter, it's a contained entity that has access to all the data and operate through well-defined methods and boundries. Therefore /clever/ people thought... Ahaaa, let's move as much logic as we can out of the view and into the presenter/viewmodel, 'cause that we can test and control... and it can help "Beautify" the presentation of our data \o/\o/\o/
This "as much logic" gets interpreted gradually to "a lot", "most" and "some", all depending on the situation at hand. There are also people leaning towards the philosophy of "1 presenter per view" -> to the same model, again it comes down to requirements & taste.

Look at it like a restaurant....
View          Presenter          Model
1 guest -> 1 waiter -> 1 kitchen(1 cook)
1..15 guests -> 1 busy waiter -> 1 kitchen(1 busy cook)
more         maitre'd(more waiters)        still 1 kitchen{chef}(more cooks)
Guest places order with waiter, who orders the cook to ...eh cook ...->
meal cooked -> handed to waiter(checks and wipes plate) -> who sends a young waiter along to deliver the meal to the guest

A) Yes also the presenter has different objectives/tasks. It too exposes more
    objects than functions in its API, with rising complexity ...Tadahhh more
    units under one entity.

The size and complexity is a balancing act, to have great functionality and a compact size, as not to create "Monoliths".

Pheeewww, I hope this answers a couple of your questions....
Regards Benny
« Last Edit: January 21, 2024, 08:59:05 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Hansvb

  • Hero Member
  • *****
  • Posts: 864
Re: Best way to exchange data between a form and a unit
« Reply #47 on: January 21, 2024, 02:11:21 pm »
First of all, thanks again for the effort. It is an extensive explanation.
Quote
Pheeewww, I hope this answers a couple of your questions....
I could ask ...  O:-)



I'm slowly making some progress (I think).

I added 2 buttons. Both adjust the caption of the form.
This works in itself, but I make a mistake with FPOObservedChanged (Form1). See lines 178-180 in unit hvb_viewmain. It seems that I cannot have both function calls active at the same time within 1 Operation.
What am I doing wrong then? Or do I have to create a customOperation for each function call in FPOObservedChanged?


And further... This one took me half an hour before I saw what happened.  :-[ I have never used result in this way before. This is very useful!

Code: Pascal  [Select][+][-]
  1. function TModel.FetchViewTextsFull: TStaticTextsAll;
  2. get started
  3.   with Result do begin
  4.   ...

I probably would have done it like this:
Code: Pascal  [Select][+][-]
  1. function TModel.FetchViewTextsFull: TStaticTextsAll;
  2. var
  3.   lRec : TStaticTextsAll;
  4. begin
  5.   lRec.staBtnResetCaption:= '&Reset';
  6.   lrec.staLblPrgressCaption := 'Level of insanity:';
  7.   ...
  8.   result := lRec;
  9. end;            


Edit:
found the errors. see the new attachment.

I works now. But is it any good?
« Last Edit: January 21, 2024, 04:35:50 pm by Hansvb »

Hansvb

  • Hero Member
  • *****
  • Posts: 864
Re: Best way to exchange data between a form and a unit
« Reply #48 on: January 21, 2024, 04:01:16 pm »
There is still something wrong. The string from the model does not end up in the form caption.

Unfortunately, I still don't get it. My example with the two buttons is wrong.
The model returns a string to the presenter, but the string is not returned to the view.
« Last Edit: January 21, 2024, 04:24:10 pm by Hansvb »

cdbc

  • Hero Member
  • *****
  • Posts: 2522
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #49 on: January 21, 2024, 04:47:01 pm »
Hi
I'll have a looksee, hang on a bit, I'm watching football (Bayern - Werder Bremen)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Hansvb

  • Hero Member
  • *****
  • Posts: 864
Re: Best way to exchange data between a form and a unit
« Reply #50 on: January 21, 2024, 05:29:42 pm »
I will wait. I already have closed my pc for today.  :D

jamie

  • Hero Member
  • *****
  • Posts: 7405
Re: Best way to exchange data between a form and a unit
« Reply #51 on: January 21, 2024, 09:07:33 pm »
I got an idea, SOCKETS in each unit, Sever and client!

Use the CLOUD Luke!  %)
The only true wisdom is knowing you know nothing

Joanna

  • Hero Member
  • *****
  • Posts: 1401
Re: Best way to exchange data between a form and a unit
« Reply #52 on: January 21, 2024, 10:04:17 pm »
Using observers seems very complicated...

egsuh

  • Hero Member
  • *****
  • Posts: 1712
Re: Best way to exchange data between a form and a unit
« Reply #53 on: January 22, 2024, 02:49:08 am »
I have no intention to downgrade MVVM- king of framework, and I tried to understand it myself. But I found following criticism on Wikipedia (https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel), which I believe may will experience.

Quote
Criticism

John Gossman has criticized the MVVM pattern and its application in specific uses, stating that MVVM can be "overkill" when creating simple user interfaces. For larger applications, he believes that generalizing the viewmodel upfront can be difficult, and that large-scale data binding can lead to lower performance.

I need something like that, but I'm still hesitating entering the area.

Jiyahana

  • New Member
  • *
  • Posts: 12
Re: Best way to exchange data between a form and a unit
« Reply #54 on: January 22, 2024, 06:51:25 am »
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?

It's efficient to use properties in the unit rather than including the form in the units uses clause. This checks a cleaner separation of concerns and facilitates better maintainability, define properties in the unit to interact with the forms data.

cdbc

  • Hero Member
  • *****
  • Posts: 2522
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #55 on: January 22, 2024, 12:55:51 pm »
Hi
Right, first things first...
@jamie:
Quote
I got an idea, SOCKETS in each unit, Sever and client!
Use the CLOUD Luke!  %)
Hehehe, that's how MVC came to be: "websites", sockets, that is  :-X
Cloud(s): Maybe later in our little study-group...

@Joanna:
Quote
Using observers seems very complicated...
You're right Joanna, at this point in our journey, it seems a little daunting, but stay tuned, there's more to come. Especially 'bout them observers, there's a new player in town: "obs_prosu.pas" in today's attachment  8-)
It deals with the shortcomings of the built-in "IFPObservxx" framework and distances us from LCL-dependent classes. In today's project, it's pretty easy.

@egsuh:
Quote
I need something like that, but I'm still hesitating entering the area.
I too, have read all those different opinions and come to the decision "Maybe it's woth the trouble, I'll give it a try". Welcome to our little study-group, where we'll try to find a way, that's easy, simple & /underkill/  :)

@Jiahana:
Quote
It's efficient to use properties in the unit rather than including the form in the units uses clause. This checks a cleaner separation of concerns and facilitates better maintainability, define properties in the unit to interact with the forms data.
Well, yes and that is pretty much where we started our study of MVC, MVP, MVSupervising Presenter & MVVM(without data-binding language a'la M$)
If in doubt: Follow @Thaddy's excellent & simple example at the start of this thread...

Finally Hansvb  :D
I've looked and made a few/some changes to your project, so it is imho, how the project should look, going forwards, haven't done the transactions yet.
It's time for the next chapter... Your own observer framework, it's in the attachment. The built-in is too limited for our uses...
We are doing away with the built-in IFPOxxx(lcl_observer.pas you can use for other things). This gives us a) a much 'quiter' view, b) simpler coding & c) the possibility to switch views 'in situ' if we feel like it => less noise and easier to follow code/data -flow.
The code slowly adheres to the pattern, where model does data/logic(most), presenter does reaction to actions from user, communication and pretty presentation and the view(has gotten stupider) surfices to display data and convey clicks.
I realise, there are some new aspects for you to get your head around, but given your practice with the former projects, I think you'll do just fine  8)
It's where I think our project with your new additions is supposed to be at.
Have a look and tell me what you think...  ;)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Hansvb

  • Hero Member
  • *****
  • Posts: 864
Re: Best way to exchange data between a form and a unit
« Reply #56 on: January 22, 2024, 08:05:26 pm »
Hi, I looked at it but it's too difficult for today. I can't follow the process in debug mode.
I'll try again tomorrow.


Hansvb

  • Hero Member
  • *****
  • Posts: 864
Re: Best way to exchange data between a form and a unit
« Reply #57 on: January 23, 2024, 08:35:15 pm »
Hi,
Sorry but the last example is way too difficult for me. I don't understand what is happening and I am having trouble with obs_prosu.pas.

I stepped back and dropped the observers. what if I just pass things to the presenter and then to Model and back? See attechment. I think the presenter is also redundant in this test, and then I come close to @Thaddy's example. (I think).

That doesn't change the fact that I would actually like to understand the last example (use observers).

cdbc

  • Hero Member
  • *****
  • Posts: 2522
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #58 on: January 24, 2024, 08:12:36 am »
Hi
I had a look at your example and you do understand the concept of 'moving the logic out of the view'. Also, you're right, in this example, if you leave out the presenter, you're back to @Thaddy's example. So far so good.
If I were to write a console-view to your example, instead of a form, I might /not/ have any buttons?!? ...or edits, for that matter......  %)
Quote
Sorry but the last example is way too difficult for me. I don't understand what is happening and I am having trouble with obs_prosu.pas.
No worries mate, I'll walk you through it, here online when you've got the time, step by step, just say when  ;)
The "obs_prosu.pas" is a <BlackBox>, you connect it in both ends and it does your communication for you. That's it! Just like the IFPOxxx objects hidden in the LCL (or lcl_observer.pas) does for the various parts of the LCL.
You don't need to worry about it.
Quote
That doesn't change the fact that I would actually like to understand the last example (use observers).
Pheeewww, That's good, I was afraid, that I'd scared you off  :)
I'm convinced that, when we break down 'hvb_play v2', in its components, you'll see the light...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

cdbc

  • Hero Member
  • *****
  • Posts: 2522
    • http://www.cdbc.dk
Re: Best way to exchange data between a form and a unit
« Reply #59 on: January 24, 2024, 12:16:25 pm »
Hi
The MVP from 22.01.2024 is working nicely...
Powered by @Warfley and his nifty little "LazTextForm" library. Thanks to him, I've now got buttons & edits in a console app \o/\o/\o/
Attached is the first screenshot of "hvbplayTUI" running on PCLinuxOS...
The lpr looks like this:
Code: Pascal  [Select][+][-]
  1. program hvbplayTUI;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   {$IFDEF UNIX}
  5.   cthreads,
  6.   {$ENDIF}
  7.   Classes, hvb_presenter,hvb_viewtui, TFCanvas;
  8.  
  9. {$R *.res}
  10. var Canvas: TTextCanvas;
  11. begin
  12.   Canvas:= TTextCanvas.Create;
  13.   Canvas.Width:= 80;
  14.   Canvas.Height:= 25;
  15.   with TViewMainTUI.Create(Canvas) do try
  16.     Presenter:= TPresenter.Create; // attaches messaging and model, owns it
  17.     Show;
  18.   finally
  19.     Free;
  20.     Canvas.Free;
  21.   end;
  22. end.
The UI is only half-baked at the moment  :D
I thought "What the h***, why not..."
Proof of concept...
edit: Found an error in the model, can you spot it? It assumes stuff about the captions....
Regards Benny
« Last Edit: January 24, 2024, 12:25:14 pm by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

 

TinyPortal © 2005-2018