views:

602

answers:

7

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

+1  A: 

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.

Gamecat
+3  A: 

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.

birger
Also see http://tiopf.sourceforge.net/Doc/overview/index.shtml
SeanX
+1  A: 

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).

Yogi Yang 007
Actually I've been the most successful in my experiments with Instant Objects, apart from a few annoyances. However, during the gui - model interaction and seperation I stopped to consider other alternatives (even develeoping my own :)). (Not being able to clearify going dbaware or non-dbaware was the cause). However, it worked like a charm in the persistence part for me. You just call Store() and that's it. No sql, no field list, field names, no typecasting etc, no datetime type mismatch...
+7  A: 

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 :)

Despatcher
You mention that each list should contain code to manipulate.load.save data. That is wrong. The class model should have no idea about how it is connected to a database. Persistence should be taken care of by separate classes.Also, creating datamodules wit lots of separate SQLQuery controls is not necessary. You create query objects when they are needed, dynamically creating SQL to perform certain tasks.OO programing without data-aware controls is about 3 layers: GUI, model and persistence.
birger
@birger - Its not clear I know, but limited space and time. The lists and objects need to be able to perform or initiate saves/loads. I did not say they knew what they are connected to. Also I took it one level further and created my own "DataManager" to separate it one level further the objects only use that. SQL - you create it on the fly if you like, I don't like it and I don't see the need for most business apps. Try debugging the program statements that created it in place of hitting F11 to read straingt text. Having said that I do have aan SQLQuery object that creates SQL for reports
Despatcher
Despatcher thank you for your long explanation, also thanks to birger. The three layer idea fits into my mind somehow. Just websearching I could not make out the difference between the persistence and model layer. People mentioning 3 letter acronyms get you lost. Rather than your objective, you start going after the new terms (opf/orm/mgm etc..) Maybe it is much simpler. You write a connection class, instantiate it at app start or login etc. You write a sql class, instantiate it according to user action and on. Make these highly reusable and decouple from db access technology. A good start ?
+1  A: 

Jazz SDK Value Type, OPF and MVP Frameworks

Cesar Romero
This may be a good SDK but it documentation is not in English that is the biggest problem.Do care to add English documentation to this product.
Yogi Yang 007
I do aggree with Yogi Yang. It's much easier to create from scratch against getting to understand a code w/o documentation (lack of English I mean)
There is some other called infra framework. It is rather much strange, no download link is supplied. Only svn access. I think it is also in Portuguese
+1  A: 

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.

skamradt
A: 

If you are looking for a framework, Data Abstract is the best tool I know for this thing.

Giorgio Gelardi