From your description I’m going to assume you’ve got a VCL application that is in the traditional Delphi RAD style using dataaware controls, with quite a bit of code in the actual forms themselves and probably a single datamodule. My apologies if these assumptions are not correct.
Reworking that sort of application to something like MVVM, MVP, MVC is not going to be easy. It’s more than likely a complete rewrite which you probably don’t want to do.
Assuming a complete rewrite is off the cards my advice would be incrementally improve your existing application from being a “hobbyist” RAD application to a more structured RAD application. It won’t be perfect but it will be more maintainable than it is now.
There actually is no universally accepted best practice for a Delphi RAD application but here’s a few rules of thumb to start the process of improving your code maintainability. The most important principle is to structure your application into layers.
At the Bottom - The user interface layer - your forms
- Put as little code as possible in your form units. Ideally the code in your forms should all be about displaying things on screen.
TDataSource components can go on forms but
TQuery components should go in the data access layer on datamodules.
- All forms should be created on demand and freed once they are no longer needed. The main form is the only form that you should leave as auto-created.
In the Middle - The data access layer - your datamodule(s)
- A single datamodule quickly becomes a maintenance nightmare for any non-trivial application.
- Create multiple datamodules each one responsible for a specific aspect of your application. e.g. the person datamodule, the payment datamodule, the book borrowing data module. Each of these datamodules has the
TQuery components for that area of the database on it.
- Have just one DB connection component
TADOConnection in your application and put it on a single datamodule that is responsible only for maintaining that database connection.
- Only that database connection datamodule should be autocreated, all the others should be created on demand and disposed of when you are finished with them.
- Splitting the current single datamodule into multiple datamodules can be tricky. Be methodical and leave the original datamodule intact so you can easily switch between a new subsystem datamodule you’ve just created and the original single datamodule.
- You’ll also need to leave your current single datamodule as being auto-created until you’re finished splitting it apart and are ready to dispose of it completely.
At the Top - The Logic layer - new units containing plain old Delphi classes (e.g. derived from TObject)
- You will probably have code that you need to be shared between the different datamodules. Put this code in classes that are in their own separate units.
- Don’t worry if you don’t have a lot of code to put in these classes, in a RAD style application a lot of the code that would be in this layer is replaced by dataset components and their event handlers.
Very importantly, keep your layering sound by making sure no unit never adds a unit to its
uses clause from a lower layer. So a logic layer should never use a datamodule or a form, and a datamodule should never use a form.
And of course before embarking on any sort of major refactoring like this your project needs to be in a version control system, but that’s a whole other topic.