3 tier class design help

hooks

Registered User.
Local time
Today, 13:06
Joined
Aug 13, 2004
Messages
160
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
 
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.
 
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
 
Last edited:
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.

Code:
'-- 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
 
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
 
hooks said:
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
 
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?
 
Last edited:
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
 
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
 
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.

Code:
    Private Sub btnGetCustomers_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGetCustomers.Click

        Dim objCust As BTCustomers.clsCustomer

[COLOR="SeaGreen"]	'This is the the global sorted list that i use to store the object[/COLOR]
        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.

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)

[COLOR="SeaGreen"]        'these are all read only fields so just load into text field[/COLOR]
        Me.txtCusotmerID.Text = objCust.CustomerID()
        Me.txtCustomerFirstName.Text = objCust.CustomerFirstName()
        Me.txtCustomerLastName.Text = objCust.CustomerLastName()
        Me.txtCustomerEMailAddress.Text = objCust.CustomerEMailAddress()

[COLOR="SeaGreen"]	'Here is where the problem is[/COLOR]
        Me.comboboxCustomerStatus.Text = objCust.CustomerStatusID()
	[COLOR="SeaGreen"]'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.[/COLOR]

    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
 
hooks said:
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
 
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
 
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

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

[COLOR="Red"]Dim objCustStatus as BTCustomerStatus.clsCustomerStatus
[COLOR="SeaGreen"]'The FindCustomerStatus() below finds the customerstatus based on the customerID[/COLOR]
me.comboboxCustomerStatus.text = objCustStatus.FindCustomerStatus()
[COLOR="SeaGreen"]'I know the above code isn't proper but you will figure out what i am doing.[/color]
[/COLOR]
    End Sub

Maybe i am getting ahead of myself.

Sorry if i am confusing anyone.

Thanks Hooks
 
Last edited:
it doens't know anything about the business layer, it is only accessing a method of the object.
 
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
 
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
 
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
 
hooks said:
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
 

Users who are viewing this thread

Back
Top Bottom