I'm working on a web app that keeps track of some user/event information and in the course of roughing out classes I find that I am duplicating alot of the same fields. For example, states and countries. My states and countries are made up of the following
fields: ID, Name, Shortname. So what makes more sense?
public class Person
{
private int id;
private string firstname;
private string middlename;
private string lastname;
private string city;
private int stateID;
private string state;
private string stateShortname;
private int countryID;
private string country;
private string countryShortname;
public int ID
{
get {};
set {};
}
public string Firstname
{
get {};
set {};
}
public string Middlename
{
get {};
set {};
}
public string Lastname
{
get {};
set {};
}
public string City
{
get {};
set {};
}
public int StateID
{
get {};
set {};
}
public string State
{
get {};
set {};
}
public string StateShortname
{
get {};
set {};
}
public int CountryID
{
get {};
set {};
}
public string Country
{
get {};
set {};
}
public string CountryShortname
{
get {};
set {};
}
}
OR should I try to do something more object oriented like this:
public class Person
{
private int id;
private Name name;
private string city;
private State state;
private Country country;
public int ID
{
get {};
set {};
}
public Name Name
{
get {};
set {};
}
public string City
{
get {};
set {};
}
public State State
{
get {};
set {};
}
public Country Country
{
get {};
set {};
}
}
public class Name
{
private string first;
private string middle;
private string last;
public string First
{
get {};
set {};
}
public string Middle
{
get {};
set {};
}
public string Last
{
get {};
set {};
}
}
public class State
{
private int id;
private string name;
private string shortname;
public int ID
{
get {};
set {};
}
public string Name
{
get {};
set {};
}
public string Shortname
{
get {};
set {};
}
}
public class Country
{
private int id;
private string name;
private string shortname;
public int ID
{
get {};
set {};
}
public string Name
{
get {};
set {};
}
public string Shortname
{
get {};
set {};
}
}
I guess I am just looking for suggestions and/or a reality check on this. I feel like I might be over-engineering this, but it does make the code read much better using the intellisense.
Hi TonyC, 1. I do not know if there is an equivalent relationship between Datbase design and Class design. However database designwise, I see 3 tables - see point 2 - Classwise, I see we have a 'Composite' pattern for your classes. I see 3 classes - see point
3 - 2. Database design
--Person table
id (personid)
firstname
middle name
lastname
stateid (Referential Integrity with State table)
--State table
stateid
statename
stateshortname
countryid (Referential Integrity with Country table)
--Country table
countryid
country
countryShortname
3. Class design
--Person class
id (personid) int
firstname string
middle name string
lastname string
State object of State class
--State class
stateid int
statename string
stateshortname string
Country object of Country class
--Country class
countryid int
country string
countryShortname string
Where there is a will, there is a way.
and where there is a team, there is more than one way.
Hey Phuoc, What you have is very close to what I have currently in the database. One slight difference though. If someone is from a country that does not have state/province, the Person.State field becomes optional. So would you still organize it the same way
or do something like this:
--Person class
id (personid) int
firstname string
middle name string
lastname string
State object of State class
Country object of Country class
--State class
stateid int
statename string
stateshortname string
Country object of Country class
--Country class
countryid int
country string
countryShortname string
Hi TonyC, 1. ::One slight difference though What you have is very close to what I have currently in the database. One slight difference though. If someone is from a country that does not have state/province, -Yes. This is business requirement for some foreign
countries that I did not see from your requirement. No problem. That's was the reason I did not include Country object into the Person class. So the Person table --Person table id (personid) firstname middle name lastname stateid (Referential Integrity with
State table) countryid (Referential Integrity with Country table) -Then "how do you enforce the referential integrity for optional state?" this is the key point here because state can have NULL value or a value matching the state table. How do you enforce
RI for NULL value unless you have one null value in your state table? which implies there must be one NULL value in the Country table by the reason of RI between Country and State tables. -In the case for a person with a state and country, then that person
will have 2 values for those 2 columns and the state table will also have a country value as well. 2. This point 2 depends on the point 1's outcome. However, I've a question: :: --Person class id (personid) int firstname string middle name string lastname
string State object of State class Country object of Country class The fact we have Country object would handle point 1 (business rule). But then the programming implication is we have to check if state object is not optional (not null/nothing) then we have
to ignore country object else ignore state and use country object. Is this what you have in mind? 3. We'll have a comprehensive look again based upon your answer for point 1 and 2.
Where there is a will, there is a way.
and where there is a team, there is more than one way.
TonyC, Additional note for previous point 1 of previous post: -If State can have a NULL value to enforce R.I for optional state, then you must be careful during the Insert into the Person Table which implies your front-end validation must be strict and well
tested because people can enter a NULL for state by mistake then NULL can be accepted since state table has a NULL. Your code would not be able to know whether the customer is having optional state or not.
Where there is a will, there is a way.
and where there is a team, there is more than one way.
Just to kind of clean the code up a bit so we can clearly see what we are discussing (I realize our naming conventions are alittle different but bear with me).
--- Person Table
ID int (PK)
Firstname varchar(50)
Middlename varchar(50)
Lastname varchar(50)
State_ID int (FK for State table)
Country_ID int (FK for Country table)
--- State Table
ID int (PK)
Name varchar(50)
Shortname varchar(5)
Country_ID int (FK for Country table)
--- Country Table
ID int (PK)
Name varchar(50)
Shortname varchar(5)
--- Person Class
ID int
Firstname string
Middlename string
Lastname string
State object of State class
Country object of Country class
1. Currently, I just do left joins on the Person and State tables. If there is no match for
the state, the sproc returns null values for state information. There is another left join for the country that works the same way. I tinkered with putting a null placeholder in the State and Country tables, but I didn't like the way that worked. Maybe I'm
wrong here. 2. I'm struggling with that part too. The trick to that would probably have to be in the properties of the Person class. On a set for the State, you would copy the state in to the Person.State and copy the Person.State.Country to the Person.Country
field. Or you could set the Person.State and skip a set for the Person.Country. On the get for Person.Country, you could first check if Person.State is null. If it is, then return the country field, otherwise return Person.State.Country. Does that help/make
sense?
Tony, ::Currently, I just do left joins on the Person and State tables. If there is no match for the state, the sproc returns null values for state information 1 quick question before I proceed further: Right now, is your database already set up and used in
production OR is it in design mode as we discussed now?
Where there is a will, there is a way.
and where there is a team, there is more than one way.
Tony, 1. Before we consider my question #2 and your #2 (which are about Class design). Let's have a common ground first. -My question # 1 is concerned about designing first which focused on R.I for the optional state requirement. See Posted: 08-05-2003 11:22
AM, Posted: 08-05-2003 11:45 AM -Your # 1 (Posted: 08-05-2003 12:00 PM) is about data access (SELECT) which is OK but that would not be possible at this stage since my question # 1 has not been fully answered yet. Please read that question again and let me
know if we're on the same level. In addition to my question#1 on the previous 2 mentioned posts: How can you insert a row into a Person table for a optional state given there is a R.I between Person table and State table. E.g: -INSERT INTO PERSON VALUES (2,
'TONY', 'C', 'TONYLASTNAME', 'what is the value for optional state that would match the value in State table by R.I'
,1) 3. If possible, set up a sample of data/values for rows for the 3 tables that you see from your point of view.
Where there is a will, there is a way.
and where there is a team, there is more than one way.
Phuoc #1: The answer is null. If there is no state selected, I just insert a NULL. There is no row in the State or Country table that represents a blank. Should there be? Does that answer your question?
INSERT INTO Person (Firstname, Middlename, Lastname, State_ID, Country_ID) VALUES ('Gerry', NULL, 'MacNamara', NULL, 3)
Phuoc #3:
Person Table
ID Firstname Middlename Lastname State_ID Country_ID
------- --------------- --------------- --------------- --------------- ----------
1 Tony C 1 1
2 Konstantine Pavlov 2
3 Gerry MacNamara 3
State Table
ID Name Shortname Country_ID
------- ------- --------------- ----------
1 Texas TX 1
2 Utah UT 1
3 Alaska AK 1
Country Table
ID Name Shortname
------- --------------- ---------
1 United States USA
2 Russia RUS
3 Ireland IRE
TonyC
Member
140 Points
32 Posts
Class Design
Aug 04, 2003 09:55 PM|LINK
public class Person { private int id; private string firstname; private string middlename; private string lastname; private string city; private int stateID; private string state; private string stateShortname; private int countryID; private string country; private string countryShortname; public int ID { get {}; set {}; } public string Firstname { get {}; set {}; } public string Middlename { get {}; set {}; } public string Lastname { get {}; set {}; } public string City { get {}; set {}; } public int StateID { get {}; set {}; } public string State { get {}; set {}; } public string StateShortname { get {}; set {}; } public int CountryID { get {}; set {}; } public string Country { get {}; set {}; } public string CountryShortname { get {}; set {}; } }OR should I try to do something more object oriented like this:public class Person { private int id; private Name name; private string city; private State state; private Country country; public int ID { get {}; set {}; } public Name Name { get {}; set {}; } public string City { get {}; set {}; } public State State { get {}; set {}; } public Country Country { get {}; set {}; } } public class Name { private string first; private string middle; private string last; public string First { get {}; set {}; } public string Middle { get {}; set {}; } public string Last { get {}; set {}; } } public class State { private int id; private string name; private string shortname; public int ID { get {}; set {}; } public string Name { get {}; set {}; } public string Shortname { get {}; set {}; } } public class Country { private int id; private string name; private string shortname; public int ID { get {}; set {}; } public string Name { get {}; set {}; } public string Shortname { get {}; set {}; } }I guess I am just looking for suggestions and/or a reality check on this. I feel like I might be over-engineering this, but it does make the code read much better using the intellisense.Phuoc
Participant
1150 Points
230 Posts
Re: Class Design
Aug 05, 2003 02:28 AM|LINK
and where there is a team, there is more than one way.
TonyC
Member
140 Points
32 Posts
Re: Class Design
Aug 05, 2003 02:04 PM|LINK
Phuoc
Participant
1150 Points
230 Posts
Re: Class Design
Aug 05, 2003 03:22 PM|LINK
and where there is a team, there is more than one way.
Phuoc
Participant
1150 Points
230 Posts
Re: Class Design
Aug 05, 2003 03:45 PM|LINK
and where there is a team, there is more than one way.
TonyC
Member
140 Points
32 Posts
Re: Class Design
Aug 05, 2003 04:00 PM|LINK
Phuoc
Participant
1150 Points
230 Posts
Re: Class Design
Aug 05, 2003 08:07 PM|LINK
and where there is a team, there is more than one way.
TonyC
Member
140 Points
32 Posts
Re: Class Design
Aug 05, 2003 08:20 PM|LINK
Phuoc
Participant
1150 Points
230 Posts
Re: Class Design
Aug 05, 2003 10:11 PM|LINK
and where there is a team, there is more than one way.
TonyC
Member
140 Points
32 Posts
Re: Class Design
Aug 05, 2003 10:41 PM|LINK
INSERT INTO Person (Firstname, Middlename, Lastname, State_ID, Country_ID) VALUES ('Gerry', NULL, 'MacNamara', NULL, 3)Phuoc #3: