Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi: Good pattern/strategy for view <-> model synchronization

There's a lot of talk about model-view-controller, model-view-viewmodel, model-view-presenter and so on these days.

What do you see as the best pattern for use with delphi and non-data aware components?

How do you usually implement it?

like image 373
Vegar Avatar asked Oct 13 '09 21:10

Vegar


2 Answers

You can use the Model View Presenter pattern in his Passive View variation. Some time ago I wrote a post about it. http://www.danieleteti.it/?cat=18

You can use Model Gui Mediator too (http://www.andypatterns.com/index.php/design_patterns/model_gui_mediator_pattern)

like image 169
Daniele Teti Avatar answered Sep 19 '22 14:09

Daniele Teti


The purpose of MVC is decoupling. Decoupled systems are clearly much easier to maintain, and arguably easier to develop in the first place. Can you radically change your DB design without affecting your GUI code? Can your GUI completely change without impacting too much on your DB design? Is the consistency of data in the DB independent of the order in which GUI, or form-based events occur? These are the questions that really matter, and MVC is an approach to answering those questions in the positive.

I am not an expert, but I have been burned by these few things in the past:

  1. Attempt to put all explicit references to DB access, and DB-access components inside a data-module. It doesn't matter too much if you err on the side of too many datamodules, but be careful not to put too many non-related DB-access items in the same datamodule (combining code is much easier than separating code).

  2. Though it is very convenient to wire all your DB components up to the main connection/session component at design time (and doing so is one of Delphi's strengths), it is also very useful to be able to explicitly set the connectionString, or session, or connection reference dynamically at runtime, particularly when one wants to use the data-module in a different project, without having to add in the original project's DB connection unit, if one exists.

  3. Do your very best to put as little business logic as possible into your component events. This is a natural extension of not using data-aware components. It is difficult to keep to this because doing it consistently seems like doing extra work, especially in a new project, and you tell yourself you'll just refactor later; of course, you know that's a lie because later never comes.

Point (3) may require an example. There is a huge difference in clarity and maintainability between the following two snippets, though it may not be obvious when one looks at them in isolation, as here:

// "LoadEntries" is (loosely) analogous to the "C" in MVC. 
// What happens /inside/ LoadEntries is the Model, 
// and button interaction is part of View functionality.  
// MyList may also be viewable on screen as part of
// the View.
procedure TForm.Button1Click(Sender: TObject);
begin
  MyDataModule.LoadEntriesIntoMyList(MyList); // LoadEntries is the "C" in MVC
end;

instead of

// The "controller" is missing.  That omission of the essential 
// decoupling mechanism between the model and the view will 
// cost you or your company lots of money!
procedure TForm.Button1Click(Sender: TObject);
begin
  MyList.Clear;
  MyDataModule.qMyData.Open;
  while not MyDataModule.qMyData.Eof do
  begin
    NewItem := MyList.AddNewItem();
    NewItem.Blah := MyDataModule.qMyData.Fields['Field1'].Value;
    ...
    MyDataModule.qMyData.Next;
  end;
end;

I am currently reading the django book, and their MVC design is really impressive. Any part of the implementation-specific model, view or controller can be replaced by a different system without (significantly) affecting the other two. No doubt other frameworks have similar approaches, but I can't comment on those.

like image 31
Caleb Hattingh Avatar answered Sep 19 '22 14:09

Caleb Hattingh