I want to isolate database code from GUI design. For a reasonable time I've been reading/searching/skimming on topics like mgm/mvp/mvc/persistence/objects etc. I really have difficulty in designing a reusable object hierarchy/framework. Delphi is a great tool for RAD but when you want to work things out in a different way the documentation seems ineffective. I want to develop some king of persistence for data access and wiring data into an object/object list easily. And to integrate data display in a versatile manner (using existing components dbaware or not, create export/import routines for multiple formats). Where sould I start? Do you know any tutorials with code? For example mastapp demo included in Delphi installation is a great source for RAD-way as a startup. I need the equivalent in OOP :) with comments & tutorial
Delphi has quite a few database controls, which are great for RAD, but its harder to decouple database from Gui.
You can use client datasets (midas) for internal communication. They can be used with data aware controlls and have lots of other interesting properties.
If you really want to write your own object persistence framework, I highly recommend reading the documentation on the tiOPF website. Especially the concepts manual.
While you are reading this documentation you might also be interested in actually using tiOPF. It is a stable and robust persistence framework that can work with all major databases.
I have never done this but...
Have a look at Instant Objects.
For a way to build classes/objects in Delphi visually, try out ModelMaker (a commercial solution).
Hmmm. Big question, this stuff is not in the manuals:( Would really require a book to answer it. However if you are starting a new largish? project then my advice list, after 10 years doing this with Delphi, would start as follows:
Generally
THINK HARD before you start what functionality you need for version 1. But don't ignore the probability of the bells and whistles of versions 2 and 3.
Do not use data aware controls except in simple separate utility or base data entry screens.
Reasoning:
- They immediately break your GUI <-> database seperation.
- They let you down a bit at the user-friendliness test.
- They encourage Spaghetti Code
Do not use any standard or 3rd party controls including forms, frames or datamodules NATIVELY. Build your own libraries of derived classes first - even if you don't add any functionality at the start, and always use those classes instead.
Reasoning:
- Complete Control of your application's behaviour.
- Simplifies forward compatiblility.
- Grants you complete freedom to introduce new properties/functions at any point in your new component tree without having to edit all your dialogues and forms or objects.
As far a possible create everything as an object with properties that have getters where you hide complexity and setters only if they can't be read only. Discipline your self to always use your own properties - cheating with a quick public variable will normally always result in you re-creating it as a property later.
Database design - read a book :)
GUI <-> database separation.
As the Application is going to have to interact with the data then 100% separation I don't think possible. Instead your Baseline Objects will probably define at minimum:
- A mechanism to retrieve or Load data
- A mechanism to Edit that data
- A mechanism to Save the data
- A mechanism to display the data.
This I would call Loosely-coupled.
For each data table or group of closely related tables create a separate Datamodule with read-only queries, writeable ones etc. Keep the SQL as simple as possible -I moved my last app from Oracle to MYSQL in 2 days - 150 tables with related objects and edit frames:). Link them all to one pooled connection initially also in it's own Datamodule.
It sounds like you have already realised that lists, particularly TObjectLists, are your friends. Again - derive your own for each type of Object you need. I actually hide the real lists inside simpler objects. Exposing the Items and Count properties is trivial. Then you add more functionality to the base item using the internal list as necessary. From There Lists of Lists are a easy step and almost naturally follow the structure of the database data that they represent.
You can get more sophisticated with this approach by actually storing the types of the lists that different parts of your application uses/needs in the Database as well. Then you can create the correct lists on the fly without the application actually knowing what is in them - the lists and objects themselves should by that stage of your development contain all the functionality that they need to manipulate/load/save and display their own data:). This can also be extended to the functions that a list performs. I use a couple of base list types that expose simple count and items - in my case these have about 50 descendents.
Working this way your project may accumulate a large number of files but you can rely on and trust Delphi - the OO model is very strong and rarely gets caught out.
If you follow most of this your main application ends up being a list loader and that is about it :) In my latest the main functionality only occupies about 100 lines of code yet what it launches is pretty complex.
Lastly - All this is lot of work :( Getting it right first time just will not happen let's be honest, so be prepared to compromise your beautiful object model to get the app out-the-door, but make BIG comments where and why you did it and how to correct it again later.
Good luck :)
As Dispatcher stated, this is a lot of work, but it pays off in the end. I strongly suggest looking at more than one of the existing systems. Don't just settle on the first one you find. Try to understand how they work and how well your vision of your program matches the concepts of the framework.
Get a few good books on patterns. You will find them invaluable as you continue down this path and will be referenced often. I suggest GOF for the basics, and Patterns of Enterprise Application Architecture for the database object model side of things. Most of the concepts in these libraries are based on the patterns discussed in these books.
If you are looking for a framework, Data Abstract is the best tool I know for this thing.