Thanks a lot. You cleared up a lot of things, and I also did some interesting reading. I really appreciate you taking time to explain it.
In my current project (a reporting tool), I have actually used this kind of design without knowing it (I guess I'll have to buy a book on design patterns - GoF is de facto standard still?). I also have something that can be mistaken for a crude business layer. The application gets data from 4 different kind of databases, where one of them have 10 servers running at different locations. My application looks a bit like this: class DataControl select_statement - The select statement to be executed in run() valid_filter - a select statement on the data passed in run() to see if run() can be executed. is_valid(data) - runs valid_filter on data. run(data) - runs execute on all the databases. Data is a dataset containing information about what the user wants. This is passed to is_valid() to see if this DataControl is valid to run. execute() - executes select_statement on source and returns a dataset save() - saves to a localdatabase, file or something else. Say I then have 4 databases in different locations (all having the same structure, but different information). class OrderSource(DataControl) valid_filter = "SELECT 1 FROM dataset" # Always valid Override run() so it gets all the different databases, and calls execute on each. class OrderUpdate(DataControl) select_statement = "SELECT order_id, name, price, amount AS total FROM tbl_orders WHERE order_id='%d'" valid_filter = "SELECT 1 FROM dataset WHERE type='ORDER'" In run(), use OrderSource.run() with this select_statement class OrderReport(DataControl) select_statement = "SELECT * FROM tbl_local_orders" valid_filter = "SELECT 1 FROM dataset WHERE type='ORDER'" The program has ordered the datacontrols in 3 categories, datasources, dataupdaters and datareports. The datasources just connects to the databases and will run queries on them. The dataupdaters gets data and stores it in a local database. The datareports will run queries on the local database. All the different parts have valid_filters to know if they will run or not. If the user wants to update, the program loops thru all the dataupdaters, calling run. If the user wants a report, the application loops thru the datareports calling run. And of course a minimal gui on top. This seems to be a kind of CoR pattern, but also some business rules lies here in the form of valid_filter's. It is also structured with datasources in the bottom and updaters and reports above. One problem I have with this is that in order to save things to some of these databases I need to create a class for each of the queries I want to run. If I were to transform this to dabos bizobj's, how should this have been done? A solution would be to create a bizobj for each table, and a bizobj for each database (which can connect several databases). Then I could have my application run as usual updating and reporting using this, and a small gui on top. Then I could still have the updaters and reports with the concept of filters (I need to add many of these as time goes by, so I think the way with filters work ok and lets me scale the application) Is this how a pretty standard 3-tier design would be? It hits me that I need to do some serious reading on design. Amazon.com next... -Simen -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Ed Leafe Sent: 20. september 2006 14:31 To: Dabo Users list Subject: Re: [dabo-users] Buisness objects On Sep 19, 2006, at 12:24 PM, Simen Haugen wrote: > I'm having a hard time using dBizobj, and it might be that I don't > understand the underlying concept very well, but I cannot find any > decent information on the subject. Can someone recommend some reading? I don't know of any particular source, but you can do a Google search for "business object" or "3-tier" to come up with several possibilities. Here are two quick finds, one in VB and one in Visual FoxPro: http://www.jamesbooth.com/n-tier.htm http://www.asp101.com/articles/visible/vbbizobjprimer/default.asp I think it's pretty clear to most people what the UI is, and what database interaction is. The bizobj is the layer that connects the two. UIs are boring without being able to display data, and useless if they can't take what the user has entered and store it. So the UI code 'asks' the bizobj for its data, and then tells it to store what the user entered. But the bizobj 'outranks' the UI; it determines if the user should be able to see the data in the first place, and if so, it handles all the details of getting that from the database. Then when the UI tells the bizobj to save the data, the bizobj first checks to make sure that the data is valid before passing it on to the database layer for storage. This is the heart of the "business" part of the name "business object": it enforces the rules that make sense for the business application it is part of. For example, your business may have a rule that it will not accept an order from an account whose current balance is more than 30 days overdue for payment. When the UI tells this Order bizobj to save a new order, it is responsible for validating that the account is in good standing, and if not, to refuse to save the order, and return an error code so that the UI knows that there is a problem and can display that to the user. While you're Googling, also check out the 'chain of responsibility' design pattern. It is a design in which objects are not supposed to 'know' everything; all they know is their particular task, and which object to call when it receives a request it doesn't know how to do. Example: when you click the 'Save' button, it doesn't know anything except that it's supposed to tell its Form that someone clicked it. The form then gets that save() message, and since it doesn't know about the database, it passes it up the chain to the bizobj. The bizobj knows that it needs to run validation on the data, and if it fails, to return an error code. However, if validation passes, it doesn't know how to actually handle the storing of the data, so it passes the save() message to the database tier. This is the object that knows how to take the data and write it to the appropriate storage, so here is where the saving actually happens. When it is done, it returns a value that indicates success or failure back to the bizobj that called it. The bizobj passes it back to the form, which then displays an appropriate message to the user. So in a nutshell, code that deals with the display of information and interaction with the user belongs in the UI layer (form, controls). Code that deals with reading and writing to a database belongs in the data layer (dCursor). Everything else belongs in the bizobj. Hope that this helps clarify the workings of a 3-tier application design. -- Ed Leafe -- http://leafe.com -- http://dabodev.com _______________________________________________ Post Messages to: [email protected] Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users _______________________________________________ Post Messages to: [email protected] Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
