StrataFrame Forum

Design question

http://forum.strataframe.net/Topic13841.aspx

By Larry Caylor - 1/30/2008

I've just completed a project and while it works well from the user's perspective, I'm not completely satisfied with the underlying design and was wondering how other SF developers address the following situation. SF provides a one-to-one mapping between a business object and data base table. However logically, a business object might be made up of a core database table and a number of associated tables. For example a customer might be represented by a core table that contains the customer ID and name along with an associated table that contains addresses.

The most direct approach to dealing with this is to drop all of the objects on a form and add the code to the form to keep the individual objects in sync and possibly update them all on a transaction. My issue with this is that it places what I consider to be business logic in the UI.

Another approach is to create a complex business object based on the core table that exposes the associated tables as properties. This allows all of the logic that maintains the relationships to reside in the complex BO. The problem with this approach is that you cannot bind to a property such as 'customer.address.zipcode'. This can be addressed by exposing the individual properties of the contained business objects as custom properties of the complex BO, but you have to manually code the custom properties and property descriptors. And if you change an underlying table you have to update all that custom code. While I feel this approach provides a more object oriented design, all the extra manual coding undermines the productivity gains of the framework.

Any comments and/or suggestions would be greatly appreciatedSmile

By Greg McGuffey - 1/30/2008

I don't really have any magical ideas about how to accomplish this. I've done both (individual BOs dropped on the form and using custom properties to access extended BO functionality) and neither is ideal, for the reasons you've stated.



It did get me thinking about what I'd like though BigGrin



It seems to me that ideally, if a BO could have another BO as a property, and if binding could occur (your customers.address.street example got me thinking), it would be sweet. In the example, the CustomersBO would have a property of an AddressBO. This is of course possible now, but I don't believe there could be any binding in a form designer. This would continue to leverage the framework by using the BOs, but also allow for more complex scenarios. Not sure if this is a helpful idea....Unsure



I'm going to think on this some more. Great question Larry!
By Ivan George Borges - 1/30/2008

Hi Larry.

Funny this coming up now... I've been learning a lot about this subject lately, and will try to expose the ideas, so I can be part of the discussion and see if I can consolidate some knowledge.

The most direct approach to dealing with this is to drop all of the objects on a form and add the code to the form to keep the individual objects in sync and possibly update them all on a transaction. My issue with this is that it places what I consider to be business logic in the UI.

What if you created an Object Model class, a shared class handling the transaction for you. You could call it from your form, no need to create an instance of it, as it is shared, pass on your BOs as parameters and process whatever you need to do in it. You can start your Transaction, do whatever in a Try/Catch, etc.

These Object Models could reside in you Business Library, with the BOs.

Would that be a layer of Business Logic you are looking for?

By Richard Keller - 1/30/2008

I had a similiar discussion as well this week.     In fact I would like to see the BO Mapper get super intelligent and based on the Foreign Key relationships automatically link all of the objects together in a super class.   This is a feature that would be killer as part of the framework.    I'm sure that it isn't too hard to link the events and do it yourself but the time savings would be immense.  It would combine the power of Dataset style development but with Strataframe's unbelievable framework.

Thanks,

Richard

By StrataFrame Team - 1/31/2008

Much of the current design energy within StrataFrame is focusing on moving toward an Entity/Collection model that will follow the relationships defined within the database.  Therefore, you create a Customer business object which is stored in a CustomerCollection when you have more than one of them.  This Customer object then has a property on it called Addresses which is an AddressCollection.  Much more intuitive than the single-bo route. 

However, that doesn't much help you here and now, does it?  We do some stuff similar to this with our business objects that we create for reporting.  I can see if I can get together a sample of how we expose those properties.  You would have to use a BindingSource (a generic .NET one, not a BBS) to bind to the controls (like the rest of the world does Smile).  Essentially, you create a property on your CustomersBO called Addresses and it returns a BusinessBindingSource that contains a business object of type AddressesBO.  You then fill both of the BOs when you fill the customer record and the BindingSource knows how to access the Addresses property because it's a list.

By Trent L. Taylor - 1/31/2008

I am not sure that the entity collection stuff would resolve your problem entirely.  Though it might help, and what Ben was talking about as it relates to our reporting and the way we setup or BBS datasources, this is still going to require some manual code at some point.

In our medical software, we have a PhoneNumbers table that can be used by basically any parent table that has the need for unlimited phone numbers (we actually use it for any parent table that has a phone number period).  So now let's assume that I am on a patient record and I want to retrieve the primary and secondary phone numbers for reporting or display purposes (or even to update).  We expose a custom property for Primary and Secondary as these are the two that you generally deal with, but we have a shared class that all BOs that need to deal with phone numbers uses.  We also have a PhoneNumbers property that has all of the phone numbers for that patient that exposes an object model for the phone numbers (i.e. a PhoneNumber class that has all of the properties that relate to a phone number).  The only reason we have more than one property is for ease of display as it relates to items such as a report.  The PhoneNumbers collection is generally what we deal with as it relates to binding, etc.

This still aludes to a entity/object type of interface, and there will always be some level of manual setup, but if there is a structure change, the BO will not have to be modified, only the shared class that talks to the PhoneNumbers table directly.  I hope that makes sense.  But you are ALWAYS better of putting this code in an object model or BO or base BO rather than in a form so that you do not have to "reinvent the wheel" over and over again.

By Paul Chase - 1/31/2008

Hi guys

I have wrestled with the same problem.

At first was was doing as Larry stated and using the form as a container to house the logic to keep the releated business objects in sync as well as specific logic such as creating child records or whatever and keeping the business ruled in the business object.

Then I tried putting logic directly into the business object but this can get really hairy and caused me to have things blow up in my face.

What I am trying now is to put everything into a "super" class that is made up of several business objects. It basically acts like a business object container and contains logic specific to that entity. It kind of adds another layer to the business layer I leave the SF business objects in charge of common stuff such as required fields and table specific business rules and I add code that is specifc to a group of related business objects in the super class.

For instance I have a customer class that contains CustomerBo,AddressBO and several more business objects I also have and Employee class that contains EmployeeBo,AddressBO and several others. And I have logic that is common to all addresses in the regular SF addressbo and logic that is specific to a customer address in the that super class.  To have databinding work you still have to drop whatever business objects on a form and then wire them up to the business objects contained in the super class, and everything works fine.

Think of what I am doing as a container like the SF form except it is a class that inherits componentmodel.component instead of windowsforms.form . U drop you business objects into the class then write whatever code you need to make them play together the same as you would do if you dropped them on a form.

I hope this makes sence.

By Larry Caylor - 1/31/2008

Thanks eneryone for all the inputExclamation It's nice to know that I'm not the only one wrestling with this issue.

Basically what I ended up doing in my last project follows Paul's approach. Rather then expose the properties of the contained BOs as custom properties in my complex BO, I dropped the individual objects on the form and wired them up to the contained objects (exposed as properties). This solved the data binding issue but is still not as clean a solution as I would like.

I like Richard's comments regarding a super intelligent BO Mapper that understands Foreign Key relationships and is able to link all of the objects together in some super class along with all the persistance logic. This is similar to a competing framework from a company here in the San Francisco Bay area. However I'd settle for the ability to define my own super class in BO Mapper telling it which objects to incorporate, have it generate a class that contains the individual objects along with all of the properties to support SF data binding, and leave the relationship coding to me. I believe this follows what Greg was suggesting. Coding properties is so boring and time consuming and having BO Mapper create them and doing the data binding in the form designer are such great features.

Ivan's idea of using a shared class to handle transactions is something I hadn't thought of but I think I would still need a complex object to handle the specific relationships between the objects I combined. For example in my last project I had an ActivityLog object that's not exposed to the user but get updated depending on the actions taken on the complex BO.

Long term it seems like the Entity/Collection model will address many of these issues. In the meantime I'll explore the suggestions made by Trent and I'd like to see the sample that Ben discussed added to the samples library on the forum.

Thanks again for all the comments.

-Larry

By William Fields - 1/29/2011

Starting to explore the world of StrataFrame Business Objects.... searching the forums for tips and suggestions on BO design. I too am very interested in an Entity/Collection object model, or something akin to the SuperComplexBO described in this thread, but the app I'm working on is not a designed from scratch project that can be modeled to fit the SF framework. It's something that more than likely will require using the current database schema so the existing app can continue to live while a new front end is designed in .NET/StrataFrame. Meaning, VFP tables set up as linked servers in SQL, and those tables are not as neatly set up for BO mapping as I would like.

Coming from a VFP cursor based development methodology, I'd appreciate links and white papers that'll help me start off with a solid StrataFrame data object model.

But, this thread is 3 years old, have any advances been made to the SF BO model?

Thanks.

Bill
By Michel Levy - 1/30/2011

Hi William,

Why do you want to set your VFP tables as a linked server in a SQL Server?
I'm working on VFP linked server in SQL for 2 years whith the french VFP MVP, and now we know for sure that VFPOLEDB is not full compatible with the requirements of a linked server (many many errors with the PK and cdx, erratic management of the RI, management of NULLs is a monstruosity,...).

Simply map your StrataFrame BO on your VFP tables. It runs fine, with no errors. You may have an app with both VFP and SQL connection, i.e some BO are VFP based, and other one are SQL based.

You have the requirement to use the current database schema? where is the problem? you used it in VFP app, use it in SF app. Consider a SF Business Object as a super-VFP cursorAdapter Class, with enhanced PEM model.
By Edhy Rijo - 1/30/2011

Hi William,

I agree with Michael.  With SF you can work with a VFP or SQL table at the same time, this is perfect for smooth transition out of VFP front end and take advantage of the power of SF Business Objects, the end user will not notice or care if it is talking to VFP or SQL table.

Plan your design carefully, if you will be porting the application to SQL tables, then you can build a custom import process with BOs for VFP tables which will allow you to manipulate the data easily. 

I also came from a VFP background and at the beginning had many question on how to approach the VFP cursor feature in SF BO, but trust me you have by far much more power and control of the data with a SF BO than you would ever had with VFP cursor.   Take a look couple of times to the BO methods available (ex: CopyDataFrom, CurrentDatatable, AcceptChanges, etc) they will be your best friend and of course the BO.GetEnumerable() it is invaluable to loop your current data, the BO.Filter and BO.Sort are also extremely powerful and should be used with extra care, so if you set a filter or sort, you code should be aware of it to clear them up when adding new records, etc.

Again, a lot of plan and quick testing ahead of your current business rule, start playing with it, search the forums for plenty of samples and solutions, then post question here when ready to rock and roll!

Go for it Tongue
By William Fields - 1/30/2011

Hi Michael,

Thanks for the reply. I have attached a diagram of an idea I'm contemplating and I would be very happy to have comments.

Our current VFP app is "LAN bound" because of the data access design of the legacy VFP application, which means we have a separate database in each office. This is a big drawback for our users and we are trying to come up with a way to solve this limitation.

Our intention is to ultimately migrate to SQL/.NET, but we haven't been able to make a compelling argument to freeze development of the legacy app while we re-write from scratch in SQL/.NET. This being the case, we're being pressured to re-design and re-work the existing VFP app to work with data in SQL. I know this is going to be a huge undertaking and I'm trying to find an alternate path that will let us migrate incrementally while continuing to use the legacy app and VFP datastore.

I would like to prototype a linked server scenario as shown in the attached Visio document. If our StrataFrame BO's could be designed to work with data that exists on both sides of the WAN, essentially displaying a unified view of data from all offices, this would be a huge argument in favor of developing a .NET app that can work with our current VFP data. Then, as major components of the app are completed, we can move the data from the VFP tables into SQL server.

I realize the OLE DB Provider for VFP is probably the weakest link, but a huge part of the application is presentation (UI stuff) only with little actual updates needed. If we could build a beautiful presentation layer, I think we would have more clout to move parts of the VFP data into SQL and require users to use the new .NET app for parts of the app that have been "converted".

So I guess the first question is whether or not this linked server scenario is a viable design in the first place...?

If this linked server approach is viable, then I'm hoping the SF community can help me come up with BO's that are well designed not only to work with the SF framework, but also to provide a unified view of data from multiple databases via linked servers.

Thanks.
By Michel Levy - 2/1/2011

Hi Williams,

First of all, I think that today a linked server is not a viable design for other purpose than read only.
We are working with my friend Francis Faure (French VFP MVP) on a project we'll present at the next meeting of VFP french community (Rencontres AtoutFox 2011), this project is named "VFPinSQL" and is a full functional read-write linked server. In our project, we manage a dbc with triggers and RI for all tables, and pull from VFP to SQL the concurrency mode defined from within VFP. All SQL code (views and their triggers) is generated by VFP. But it is not ready today (NULLs management is not as we want it), and we are still uncertain about the necessity of a rewriting of all VFPOLEDB.

So, I'ld keep far from VFP linked server today in a production environment.

You need to use VFP tables, from within legacy VFP app and StrataFrame App. It's no problem here, the way is simply to map your BOs on VFP tables. the only difference between each LAN segment will be on the connection string.
In the same Strata app, you need to use SQL tables; these tables may be new tables, or tables from Informix linked server. You do not need 2 SQL servers, only one! This SQL Server may be on one of the LANs, or anywhere else. You'll reach it on the WAN using StrataFrame Enterprise server, which is designed for that entire purpose.

In summary...
All the time data are in VFP, map the BOs directly on VFP tables and views. When you migrate a table (or a set of tables) from VFP to SQL Server, map the BO on SQL Server. You'll have a few code to modify by yourself, but the main part will be done by the BO Mapper. In your client StrataFrame application, you may consume several connections on different data source type. You need only one SQL server, which can be reached in a secured way using StrataFrame Enterprise Server.
By William Fields - 2/1/2011

Michel,

Thanks again for your input. I have just a few items in response.

We do not have the budget to purchase the SF Enterprise Server. We see a great benefit in the product, but the cost is too prohibitive. We package/deploy/support our applications as if they were commercial apps, but our customers pay nothing to use them, so we cannot use a product without a royalty free runtime.

Thanks for your insight regarding VFP and linked server. I'm very interested in your VFPinSQL project and would like to read anything you might post to the community.

The reason for a SQL server on both sides of the WAN is that I need to access both VFP databases in the SF app on both sides of the WAN (without an SF Enterprise Server). The idea would be to set up the VFP database to the local SQL server as a linked server, then both SQL servers would be linked together as linked servers. If one of the SQL servers is not local to the VFP data, then the VFP data would have to be pulled across the WAN, which is not an option. Does that help to explain why there are 2 SQL servers in the design?
By Michel Levy - 2/2/2011

William,

I understand the 2 SQL servers on both sides, and also the fact you have not the budget for ES.

VFP data are local in each side of the WAN, are they? and will stay local, during all the smooth migrating process? If yes, then go with BO directly mapped on your VFP tables. And keep the SQL Servers as linked servers if you need it.

About VFPinSQL: we'll present it on march 23, at Montpellier (France). Maybe we shall put the code on CodePlex, but we don't know when. And now, we need to find a solution for the NULLs Crazy, and also for a problem with grants on automation Ermm.