View Full Version : 3 tier class design help
hooks 01-18-2006, 03:13 PM Hey all, I have played around with a 3-tier design for about 1 year and am able to make your basic applications using them.
My problem is this. Say that you have a Customer class. I would populate a list box on a form with the customer object and when a user selects a customer all the other fields would be displayed in text boxes / combo boxes on the form. The problem is that the state field would show the ID of the states table and not the state name. How would i populate a states dropdownlist on the customers form so that the user could select which state the customer lives in? Do I create a states class? If so how would I incoprorate it in the customer class? Do i just use a sql statement in the code behind the form, which pretty much ruins the whole 3 tier thing?
My business tier classes look like this. clsCustomer and clsCustomers. clsCustomers is i guess a helper class to the clsCustomer. clsCustomer has all of the properties and the clsCustomers has all of the update/delete functions.
I hope this all makes sense.
Thanks Hooks
pono1 01-18-2006, 03:53 PM Because the info is static, I would consider including the state data in the front-end -- in a MDB or even in an XML file -- and query it to fill your dropdown control. No network traffic, snappier performance.
Regards,
Tim
I agree with pono1. States are changing any time soon so why not put them directly into the html or an xml file which you can bind to the control.
hooks 01-19-2006, 02:47 PM Thanks guys, I was just using states as an example.
Say i have a customer object that populates a list box. Upon clicking the list box all the other customer fields are displayed. Say i have a CustomerGroup and a CustomerStatus class both of which are combo boxes on the customer form. Do i reference the Customer business tier class with the CustomerStatus and CustomerGroup class? Do i use all 3 objects in my customer form or just the customerclass. I hope this makes sense to you.
Thanks Hooks
pono1 01-20-2006, 04:31 AM In the broad context of n-tier apps, you might create another class (or two) to strictly perform data retrieval chores. This middle-tier object could, for example, expose a method named GetCustomersByAge with a parameter of Age. The code inside the method (code that you write), would query a datasource (yet another tier), returning the info in, say, a datatable to the caller.
Of course you can add a "get data and return it" method to your customer class if that works for your project. Nothing's written in stone because no two projects are exactly alike.
'-- Rough caller code --
'Get object that returns a datatable.
Dim MyObject As New YourMiddleTierDataObject
'Bind combo to datatable.
Me.ComboBox.DataSource = MyObject.GetCustomersByAge(30)
'Show the lastname field.
Me.ComboBox.DisplayMember = "LastName"
Regards,
Tim
hooks 01-20-2006, 07:52 AM So in my example i would use the customer class to populate the listbox. then when user selects a customer i would populate the CustomerStatus with the CustomerStatus class which has a GetCustomerStatus method?
Is this correct???
Thanks again, you all are great
pono1 01-20-2006, 03:20 PM So in my example i would use the customer class to populate the listbox. then when user selects a customer i would populate the CustomerStatus with the CustomerStatus class which has a GetCustomerStatus method?
Is this correct???
Thanks again, you all are great
I may not be following this exactly. Still, here goes: If the data used to populate the combos is a subset of the data in the listbox, then I would attempt to make one call to get the data, saving it -- the data -- in a "hold" container, say a datatable that has form level scope. This "local data" then can be used to populate your combos based on your users' listbox selections. That is, there's no reason to make multiple roundtrips to your remote object if all the data you need is retrieved up front. Obviously, if you require a different set of data to fill your combos, you'll need to build a method to get it -- either locally or in a middle-tier object.
Regards,
Tim
hooks 01-20-2006, 03:48 PM Sorry for not being clearer. Im still very new to this and do not know the terms needed to explain to you want i am needing.
Obviously, if you require a different set of data to fill your combos, you'll need to build a method to get it -- either locally or in a middle-tier object.
The middle-tier is what i am wanting.
The above is exactly what i am wanting. Im talking about the method to get the data to fill the combos. Should that method be in a main class/object that is populating the form(In this case it would be the cusomters class) or should it be in its own class/object?
pono1 01-20-2006, 05:10 PM Hi, Hooks,
I'd say that absolutely positively either is OK. You could, as it sounds like you have, create a customer object to do it all, to validate customer business rules and to retrieve customer data. Makes sense to me.
Or you might just use your customer object to validate customer business rules and create another object (which will be comprised of one or more classes) to do all data-related activity: accept criteria from front-end clients, query a backend DB, and return the results to the front-end(s), which can do whatever they like with data, including filling combos.
I hope I'm not confusing you too much...
Regards,
Tim
hooks 01-20-2006, 06:04 PM Im a little confused. Im going to post a whole lot more info in a few more hours so that you can see what im talking about. I beleive that we are talking about the same thing just in a different language. :)
Thanks for the help. I feel like if i can get this then ill be ok with the 3-tier design.
Hooks
pono1 01-20-2006, 07:40 PM Keep in mind that there are no absolutes when it comes to this stuff. Here's one of many articles you can find on MSDN... (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/buildntierapp.asp)
Regards,
Tim
hooks 01-20-2006, 09:19 PM Nice article. Thanks a bunch.
Im going to post a bunch of the code that i am using so that you can see how i am doing things. Im sure there are better and more efficient ways to do this but i seem to understand this method. I figured that there are a thousand ways to do it and i dont have that long to learn everything. I just want to understand this one way of doing things for now. I got a lot of this from a 15 part .net online class that was on the microsoft site. The teacher was i think Joe Hummel. Very very good class and i highly recommend it for all you beginners like me.
Basically i have a 3 tier database design.
The DataComponent handles all of the Read, Insert, Update and delete functions.
The businessComponent handles all of the logic of the program. I have 2 classes in the businesscomponent for each object that i am using in the program. For ex. I have a customer object. The 2 classes that I have for the customer object are clsCustomer which has all of the customer properties and a couple of public overrides functions and a clsCustomerS (I know not a very good naming convention) that is sort of a helper class i think, that has all of the fucntions like ReadAllCustomer. The ReadAllCustomers function returns a sorted list of of customers back to the front end component. This readallcustomers uses the datacomponent to get all of the customers from the database and put them into a sorted list.
The front end component just calls the objects helper class(in this case clsCustomers) functions in the businesscomponent to do whatever is needed.
Now in my case i am populating a list box on the form with the clsCustomers.ReadAllCustomers function.
This works fine and dandy.
Private Sub btnGetCustomers_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetCustomers.Click
Dim objCust As BTCustomers.clsCustomer
'This is the the global sorted list that i use to store the object
Globals.Customers = BTCustomers.clsCustomers.ReadAllCustomers()
For Each objCust In Globals.Customers.GetValueList()
Me.lstCustomers.Items.Add(objCust)
Next
End Sub
I then have the following code on the selectedindexchanged event of the list box to populate the text boxes and combo box on the form.
Private Sub lstCustomers_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstCustomers.SelectedIndexChanged
Dim objCust As BTCustomers.clsCustomer
objCust = CType(Me.lstCustomers.SelectedItem, BTCustomers.clsCustomer)
'these are all read only fields so just load into text field
Me.txtCusotmerID.Text = objCust.CustomerID()
Me.txtCustomerFirstName.Text = objCust.CustomerFirstName()
Me.txtCustomerLastName.Text = objCust.CustomerLastName()
Me.txtCustomerEMailAddress.Text = objCust.CustomerEMailAddress()
'Here is where the problem is
Me.comboboxCustomerStatus.Text = objCust.CustomerStatusID()
'I get the result that you would expect.
'I get the primary key of the Status table which is linked/related to the CustomerStatusID field
'In the customers table.
End Sub
Like I said, this all works perfectly and how i would expect it to work.
My question is do i make a status object and then populate the comboboxCustomerStatus combobox with the object like i did above
with the customer object? If so can and do i bind the comboboxcustomerstatus combobox to the customer object??
This is where i am really confused.
Remember the status is not static and i want to retreive it from the database.
Thanks for your patience and help. I really do appreciate it.
Hooks
pono1 01-21-2006, 07:52 AM If so can and do i bind the comboboxcustomerstatus combobox to the customer object?This is where i am really confused.
Remember the status is not static and i want to retreive it from the database.Hooks
The solution seems to be to simply adopt the technique you've already used to fill the other combo on the form... So I guess I don't quite get it. I wonder if the word bind is the key...
Regards,
Tim
hooks 01-21-2006, 02:42 PM Cool, so i just make a customer status object in the business tier and make a getCustomersStatus function and call it in the lstCustomers_SelectedIndexChanged event?
Makes sense to me. thanks a bunch.
Hooks
hooks 01-24-2006, 12:45 PM One more question, a couple of post ago i posted the code for how i am retreiving the customer object and populating the text fields on the form. The problem was populating and finding the customerstatus in a combo box for the selected customer.
Now if i add the following code to the selectedindexchange event of the combobox wouldn't this break the idea of a 3 tier application? Wouldn't it break the idea that the presentation layer of a 3 tier system shouldn't have to know anything about the business layer??? I don't beleive that you should have to pass the CustomerID to the FindCustomerStatus funtion. It should be done somehow in the business layer.
The code in red is the new code
Private Sub lstCustomers_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstCustomers.SelectedIndexChanged
Dim objCust As BTCustomers.clsCustomer
objCust = CType(Me.lstCustomers.SelectedItem, BTCustomers.clsCustomer)
Me.txtCusotmerID.Text = objCust.CustomerID()
Me.txtCustomerFirstName.Text = objCust.CustomerFirstName()
Me.txtCustomerLastName.Text = objCust.CustomerLastName()
Me.txtCustomerEMailAddress.Text = objCust.CustomerEMailAddress()
Dim objCustStatus as BTCustomerStatus.clsCustomerStatus
'The FindCustomerStatus() below finds the customerstatus based on the customerID
me.comboboxCustomerStatus.text = objCustStatus.FindCustomerStatus()
'I know the above code isn't proper but you will figure out what i am doing.
End Sub
Maybe i am getting ahead of myself.
Sorry if i am confusing anyone.
Thanks Hooks
it doens't know anything about the business layer, it is only accessing a method of the object.
hooks 01-24-2006, 04:56 PM Wouldn't you have to know the Primary Key of the customer?
me.comboboxCustomerStatus.text = objCustStatus.FindCustomerStatus()
The findCustomerStatus would need to know the ID of the customer. Wouldn't this violate the 3 tier design??
Hooks
pono1 01-24-2006, 05:28 PM Is the customerid the following?
objCust.CustomerStatusID()
If so, can you add a parameter to FindCustomerStatus, called, say, CustomerID, and pass the value to it, using that value within FindCustomerStatus to retrieve the data?
Roughly...
Dim MyCusID as Long
MyCusID = objCust.CustomerStatusID()
me.comboboxCustomerStatus.text = objCustStatus.FindCustomerStatus(MyCusID)
Regards,
Tim
hooks 01-24-2006, 05:46 PM Is the customerid the following?
Code:
objCust.CustomerStatusID()
If so, can you add a parameter to FindCustomerStatus, called, say, CustomerID, and pass the value to it, using that value within FindCustomerStatus to retrieve the data?
Roughly...
Code:
Dim MyCusID as Long MyCusID = objCust.CustomerStatusID() me.comboboxCustomerStatus.text = objCustStatus.FindCustomerStatus(MyCusID)
Regards,
Tim
Indeed. I just thought that this would violate the rules of a 3 tier design.
guess i was wrong.
thanks for all of your help
Hooks
pono1 01-24-2006, 05:55 PM Indeed. I just thought that this would violate the rules of a 3 tier design.
guess i was wrong.
thanks for all of your help
Hooks
It would be poor practice if your object had the customer id hard-coded inside of it. But it's fine to pass data to the object, as suggested.
Regards,
Tim
hooks 01-24-2006, 09:06 PM Thanks a bunch. I really do appreciate all of the help. Im sure ill be back will more questions.
Hooks
|
|