MVC and Delphi

MVC and Delphi

At work we have been discussing the MVC model as part of a project, but the more I think about it, the less appealing it feels.

To me, it seems like turning classes into a graphic component is far more appropriate than making a Model object, a View object and a Controller object.

Am I missing something?

Comments

  1. Probably this book http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612 ?
    We know nothing about your project so can't really comment. That being said, it's rarely the case for one design pattern to always be better than another one on a given problem. You need to take into consideration the entire picture, that's why you "are discussing it" ;)

    ReplyDelete
  2. I didn't mean it as project specific, I meant it as Delphi specific.

    It seems to me that the Model in Delphi is a TComponent, and a View is a TGraphicComponent. But descendents of TGraphicComponents usually handle their own business logic (as far as I'm aware), making them both Models and Views.

    As for Controllers, it seems like events are used instead, with an object receiving the signals as optional, I.E you can further pass the signal on to an object in the event function, or your can just implement it there.

    But maybe this is just a MVC model in disguise, given the 1-to-1 correspondence of parts...

    ReplyDelete
  3. This is just my understanding of the matter, it may be totally wrong and I'm sorry if this is the case.

    In pure MVC you have
    # Model: A Plain Old Dataobject with no logic
    # View: A Graphical component which knows how to display the Model
    # Controller: A place you put your logic into, triggered by other places in your code and your view (example a double click on an element in the view)

    The View knows the Model and an interface to a controller (but not a specific controller).
    The Controller knows the Model.
    The Model does not know anything.

    Example:
    Your model is a class that represents a file on your harddisk.
    Your view is a tree that knows how to display your file class.
    Your controller is a class that implements an open action.

    The view detects a double click by the user on the displayed file and calls the open action on the controller.

    The reason to do this, is to decouple your buisness logic from the way you display your items. One benefit of this is the possibility to change the way your objects are displayed by your view without touching the buisness logic. Another one may be that you can write unit tests to test you buisness logic without any graphical interface.
    Another one is, you can have differernt kind of Views for the same Model using the same (or even a different) controller.

    Back to Delphi:
    The VCL with TComponent/TControl is not to be confused with a MVC model. You can use a TComponent as a controller and a TControl as View, but you are not required to do so.

    ReplyDelete
  4. Models, Views and Controllers are not classes: they are ideas.

    ReplyDelete
  5. I use my own variation of MVC. This variation is based on the one created for an important european aeronautic company. And it is slightly different of that you describe.

    My MVC delphi implementation, has certainly 3 logic Layers, but in the number of files it have 4.
    The view, are, literally, the forms of the application. Only design. Without code. (there is no exception here).

    The Model Layer is composed by a pair of files. A DM file, without code, with some puntual exceptions, and the Model Class.
    Model descent from TCustomModel that descent from TPersistent.

    This class (file) only have methods like this...

    procedure SetDefaultValues(AItem :TClienteRow);
    function Locate(ACD_CLIENTE :string):Boolean;
    function Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions):Boolean;
    procedure Next;
    function TableIsEmpty:Boolean;
    procedure Insert(AItem :TClienteRow);
    procedure Update(AItem, OldItem :TClienteRow);
    procedure Delete(AItem :TClienteRow);

    TController or C Layer, is a file with a Class of type TCustomController, that descent from TObject.

    The controllers are the PROGRAM LOGIC. We see this later.

    The comunication between Views and Controllers is through "Delegates". Delegates are not other thing that, Event handlers implementations, created in the controller, whose each is assigned, in a process of controller initialization, to the Events of the correspondent components in the view.

    Each event happend in the view, has an action on the Controller.

    Now, the comunication between the Controller and the Model, is natural, creating a FModel instance an calling his methods.

    I know it seems complex, but not. It have a dificult barrier of learning, but when you pass this barrier, you have a great tool to create bigger good programs.

    We have an extra class to comunicate Controllers, with other Controllers and Controller with Models. This are TXXXRow classes. This classes own, in each instance a Row of Database table with his constraints. This classes are generated by an especial program.


    Now came the rules that make this pattern good.
    --------------------------
    A Controller is who instantiate both, the View and the Model.

    A Controller can be instantiated without View, to execute commands inside.

    A Controller can instantiate as many Views or Models as needed. (normally 1 & 1).
    --------------------------
    A Model, never comunicate with the View. (Only for presenting, data, with the DataBinding)

    A Model, never instantiate or comunicate with other Models.

    All the Bussines Rules are in the Model.
    --------------------------
    A View has no code, because of this it can't instantiate anything.

    ——————————————————————

    This pattern seems that limit our free of to be creative. But not. Now you know where do the creative things. Always in the controllers and sometimes in the Models.

    By other hand, you can make all the Unit Test instantiating the Controllers, without his view. You know all the item what Unit Test you should create.

    Other advantages of this pattern is the localization of the things. Example: My programs runs, with many different databases, but I have {$IFDEF...} structures with this end, ONLY INTO THE MODELS. Because of this all the Unit Test can be passed to the program, with independence of the Database for what is running the current version.

    And there exists a lot of good advantages with this patter or his variations.

    ReplyDelete
  6. Andrea Raimondi
    I agree! Because of this, when I implement a physical structure of this three layer pattern, it results in a four and half layer implementation.

    ReplyDelete
  7. Martin Wienold The Model is not a "plain old dataobject with no logic". It can be ... if that totally describes your model.

    The Model is a facade. It hides the persistence and logic part from you.

    ReplyDelete
  8. Randy Sill
    As you say this approach is good for this kind of applications in which the view layer can change.

    Example: I have a little application that has two view layers. The classic desktop interface (FMX) for manage the data of the Customers. And another project with the same Controller and Model layers, but it has no views. Instead the Controllers communicate with a group Web Service Controllers, and use them as interface (a view?).

    On the other hand, I'm making tests about the possibility of create a lot of views of my ERP for the Web, WITHOUT REPROGRAMME ABSOLUTELY the Controller and Model Layer. And in the tests it works very well.

    My ERP has been developed, at the begging, in Prism (Oxygen). The change to Delphi XE, was relatively easy. But when Delphi XE3 comes to market I decided translate all to FireDAC and FMX. The Model, and after this, the Views. The result of this was good, very good. And without lost of any functionality, because the unit test was ever executed over the Controllers and they don't change never. Neither the tests.

    I'm going to consider the possibility of dedicate a weekly time to explain my particular MVC implementation in a Blog, with a repository for the source code. For do this, I have clearly two main problems: First, the time. I'm at this moment involved in a great project and I have a little time. And Second, the language. I need a voluntary, that correct my English.

    Does any one of you animated to correct my English?

    ReplyDelete
  9. A poor man's MVC could consist of the model being a plain Delphi class, the view an almost code less frame or form and the controller a data module. You'd need tons of plumbing though.

    ReplyDelete
  10. Jeroen Wiert Pluimers
    "A poor man's MVC" could provide you more problems that advantages. ;)

    If you are going to affront this pattern, make it with a consistent architecture.

    ReplyDelete
  11. Juan C. Cilleruelo I'd go with the MVVM in DSharp or with knockoff way before even considering the poor man solution (:

    ReplyDelete
  12. What an interesting topic!
    I used the "RAD way" for years, with all logic included in my forms' code and events, resulting for bigger projects in an awful spaghetti code.
    So now I try to adapt my Delphi devs to the MVC architecture, and my thoughts are close from Juan C. Cilleruelo implementation: nothing in the Views, all their events (button clicked, ...) call the matching method in the Controller, which manages the Model(s). My Controllers can be seen as a kind of facade which manages all classes instanciantions (well not really because I also use factories where all dependency injection is achieved) and relationships between them. All my classes in Controller are interfaces.
    This method differs from Martin Wienold explanations: all my controllers are unique and I cannot specify a parent interface for all of them.

    ReplyDelete
  13. Randy Sill I found these frameworks and examples, which indeed fit for the web but IMO can be adapted to every kind of app:
    https://github.com/danieleteti/delphimvcframework
    http://blog.synopse.info/post/2014/10/24/MVC-MVVM-WebApp-mORMot

    ReplyDelete
  14. Randy Sill
    Nice to meet you Randy!

    I have an account in worpress.com. I think that if you have another account or your create one, we can contact from this service in a secure manner.

    My blog (empty blog) is sencille.wordpress.com.

    See you Randy.

    ReplyDelete
  15. Randy Sill​ start with reading through https://github.com/jpluimers/Conferences/tree/master/2015/20151020-DAPUG-Denmark-Nyborg-Hotel-Hesselet/20151020-Caliburn and https://github.com/jpluimers/Conferences/tree/master/2015/20151020-DAPUG-Denmark-Nyborg-Hotel-Hesselet/20151020-KnockOff for some current ways to get a head start. 
    (I try to make my conference and workshop materials available online so others can learn the same way I learn from public materials)

    ReplyDelete
  16. We have the first entry of this new publication! Subscribe!

    MVC for desktop, mobile and web applications. With Delphi & FireDAC!
    http://ow.ly/YAPjH

    ReplyDelete

Post a Comment