Hi
Nifty little setup, huh
Don't worry, it'll get much better as we go along...
During the creation of the view, a presenter is created (and you have access to the public methods in the presenter).
In the creation of the presenter, a model is created (And you have access to the Model). view->presenter->model are connected via a property. (or get set methods)
Yes, that's the idea, basically: The view can't live without a presenter (view is stupid, remember), which in turn can't do much without the model (Business Object Model), the model is where the app's data lives(& logic). The view /needs/ the presenter, which /needs/ the model.
In the presenter you can have functions that, when you call them from the view, trigger the presenter's observer. If a change takes place, the view is informed. And you can have functions in the presenter that first call a function in the Model. The function in the Model then returns a value or a record or something as a pointer. As I see it now, the functions in the Model must always return a value, is that correct? (Unless the model is extended and also has private methods. These are necessary for the operation within the model itself).
This returned pointer data is passed to the observer (notifyObserver) which in turn informs the view.
Is this broadly correct?
Yes, broadly speaking, that's the gist of it.
The public interface of the presenter _is_ your app's API to what it can do.
The notifications from the Observed _must_ be documented, so that the view knows how to react to them, e.g., "how do you know which TFPObservedOperation to use?"
a) In this case I choose! ...and I'm writing the view as well, so I know what
to react to = "ooPercentCalculated"
b) In case someone else is writing the view, you must document that this
"CalculatePercentage(p: PProgressRec);" method returns a record to the
observer, containing the relevant information via the ooOperation
"ooPercentCalculated".
c) I could have chosen "ooCustom" just as well, it's /generel purpose/
And what I still have trouble with is that there is something (an observer) running in the background that you cannot see into.
If it didn't work, your view would just show "dummy" texts on startup
Actually, as it should be, opaque - nothing to see here - just mechanics
When the subject/observer -pattern is working, there's nothing to see there.
It's like a conveyor belt, if it's broken you'll notice it, if not, it'll just transport stuff, all day long.
Later or maybe tomorrow, I'll show you another subject/observer and make some changes to our view...
Suppose I create a function that checks whether certain directories are present in the directory of the executable. Does this also have to go via the presenter to the model and back to the presenter? Or can that be done directly via the presenter?
Suppose the view feeds a "list" of names to the presenter-method that handles that search -> procedure TPresenter.FindDirectories(alist: tstrings);
This method then ask subject to notify observer that it should put a "Rootdir" in the supplied record(p), well back again, suppose it then feeds the model-method "ScanForDirs(aRoot: string;aList: tstrings): boolean;"
...and if that returns true, it then sends the rootdir & list to the view via subject.NotifyObservers (using ooCustom), then the view can happily show the user the results
Look at it this way:
view -> order presenter to find -> presenter needs more info ...<--- back to view <ask> -> presenter{OK} -> order model to find {model cooks up a result} <- return to presenter with result -> forward result to subject{packs in record and notifies} -> the view gets result and shows in a treeview...
Pheewww... Hope that all makes sense to you...
Regards Benny