I am new to programming so i figured i’d get help from those that know it.
I am currently writing a Registration Application which will basically take a users input, validates the data entered, displays a review screen (which the user must print out and mail in a copy), and then save the info entered to a database.
Here are the fields that need to be captured and saved.
public class Person { private string id; private string currentLastName; private string currentFirstName; private string currentMiddleName; private string currentSuffixtName; private string formerLastName; private string formerFirstName; private string formerMiddleName; private string formerSuffixtName; private string currentAddressNumber; private string currentAddressDirection; private string currentAddressStreet; private string currentAddressStreetType; private string currentAddressAptNum; private string currentAddressrCity; private string currentAddressState; private string currentAddressZipcode; private string currentAddressCounty; private string formerAddressNumber; private string formerAddressDirection; private string formerAddressStreet; private string formerAddressStreetType; private string formerAddressAptNum; private string formerAddressrCity; private string formerAddressState; private string formerAddressZipcode; private string formerAddressCounty; private string mailAddressLineOne; private string mailAddressLineTwo; private string mailAddressLineThree; private DateTime birthdate; private string gender; private string HomePhone; private string WorkPhone; private string CellPhone; private string FaxNumber; private string driversLicense; private string ssNumber; private string membershipType; private DateTime registrationDate; private string ipAddress; private string browserInfo; }
After giving this a another glance I figured i’d seperate the common stuff out and create a class for each of them and have a Person own each of the classes or an Interface for the classes. i.e.
public interface IName { string getLastName(); string getFirstName(); string getMiddleName(); string getSuffixName(); } public class Name : IName { private string _lastName; private string _firstName; private string _middleName; private string _suffixName; // Validation Methods // private set methods //#region IName Members } public interface IAddress { string getAddressNumber(); string getAddressDirection(); string getAddressStreet(); string getAddressStreetType(); string getAddressAptNum(); string getAddressCity(); string getAddressState(); string getAddressZipcode(); string getAddressCounty(); } public class Address : IAddress { private string _addressNumber; private string _addressDirection; private string _addressStreet; private string _addressStreetType; private string _addressAptNum; private string _addressrCity; private string _addressState; private string _addressZipcode; private string _addressCounty; // Validation Methods // private Set Methods // public get methods //#region IAddress Members } public interface IPerson { int getId(); IName getCurrentName(); IName getFormerName(); IAddress getCurrentAddress(); IAddress getFormerAddress(); IAddress getMailingAddress(); DateTime getBirthdate(); string getGender(); string getSSNumber(); string getPersonType(); DateTime getRegistrationDate(); string getIPAddress(); string getBrowserInfo(); string getDriversLicense(); string getHomePhone(); string getWorkPhone(); string getCellPhone(); string getFaxNumber(); string getEmailAddress(); string getSecondaryEmailAddress(); bool save(); void load(); } public class Person : IPerson { private int _id; private IName _currentName; private IName _formerName; private IAddress _currentAddress; private IAddress _formerAddress; private IAddress _mailingAddress; private DateTime _birthdate; private string _gender; private string _ssNumber; private string _personType; private DateTime _registrationDate; private string _ipAddress; private string _browserInfo; private string _driversLicense; private string _homePhone; private string _workPhone; private string _cellPhone; private string _faxNumber; private string _emailAddress; private string _secondaryEmailAddress; // private set methods // #region IPerson Members // .... Get Methods public bool save() { DataLayer dl = new DataLayer(); if (_id == 0) return dl.insertPerson(this); else return dl.updatePerson(this); } }
Here’s my datalayer insert method
public bool insertPerson(IPerson person) { bool inserted = false; SqlConnection cnDB = DatabaseConnection.GetOpenDBConnection(); try { SqlCommand cmDB = new SqlCommand('sp_InsertName', cnDB); cmDB.CommandType = CommandType.StoredProcedure; cmDB.Parameters.Add('@last_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@last_name'].Value = person.getCurrentName().getLastName(); cmDB.Parameters.Add('@first_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@first_name'].Value = person.getCurrentName().getFirstName(); cmDB.Parameters.Add('@middle_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@middle_name'].Value = person.getCurrentName().getMiddleName(); cmDB.Parameters.Add('@suffix_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@suffix_name'].Value = person.getCurrentName().getSuffixName(); int id = cmDB.ExecuteNonQuery(); cmDB = new SqlCommand('sp_InsertName', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@last_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@last_name'].Value = person.getFormerName().getLastName(); cmDB.Parameters.Add('@former_first_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@former_first_name'].Value = person.getFormerName().getFirstName(); cmDB.Parameters.Add('@middle_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@middle_name'].Value = person.getFormerName().getMiddleName(); cmDB.Parameters.Add('@suffix_name', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@suffix_name'].Value = person.getFormerName().getSuffixName(); cmDB.ExecuteNonQuery(); // Insert Current Address cmDB = new SqlCommand('sp_InsertAddress', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@address_number', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_number'].Value = person.getCurrentAddress().getAddressNumber(); cmDB.Parameters.Add('@address_direction', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_direction'].Value = person.getCurrentAddress().getAddressDirection(); cmDB.Parameters.Add('@address_street', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_street'].Value = person.getCurrentAddress().getAddressStreet(); cmDB.Parameters.Add('@address_street_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_street_type'].Value = person.getCurrentAddress().getAddressStreetType(); cmDB.Parameters.Add('@address_apt_number', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_apt_number'].Value = person.getCurrentAddress().getAddressAptNum(); cmDB.Parameters.Add('@address_city', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_city'].Value = person.getCurrentAddress().getAddressCity(); cmDB.Parameters.Add('@address_state', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_state'].Value = person.getCurrentAddress().getAddressCity(); cmDB.Parameters.Add('@address_zipcode', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_zipcode'].Value = person.getCurrentAddress().getAddressZipcode(); cmDB.Parameters.Add('@address_county', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_county'].Value = person.getCurrentAddress().getAddressCounty(); cmDB.ExecuteNonQuery(); // Insert Former Address cmDB = new SqlCommand('sp_InsertAddress', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@address_number', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_number'].Value = person.getFormerAddress().getAddressNumber(); cmDB.Parameters.Add('@address_direction', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_direction'].Value = person.getFormerAddress().getAddressDirection(); cmDB.Parameters.Add('@address_street', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_street'].Value = person.getFormerAddress().getAddressStreet(); cmDB.Parameters.Add('@address_street_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_street_type'].Value = person.getFormerAddress().getAddressStreetType(); cmDB.Parameters.Add('@address_apt_number', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_apt_number'].Value = person.getFormerAddress().getAddressAptNum(); cmDB.Parameters.Add('@address_city', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_city'].Value = person.getFormerAddress().getAddressCity(); cmDB.Parameters.Add('@address_state', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_state'].Value = person.getFormerAddress().getAddressCity(); cmDB.Parameters.Add('@address_zipcode', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_zipcode'].Value = person.getFormerAddress().getAddressZipcode(); cmDB.Parameters.Add('@address_county', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_county'].Value = person.getFormerAddress().getAddressCounty(); cmDB.ExecuteNonQuery(); // Insert Mailing Address cmDB = new SqlCommand('sp_InsertAddress', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@address_number', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_number'].Value = person.getMailingAddress().getAddressNumber(); cmDB.Parameters.Add('@address_direction', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_direction'].Value = person.getMailingAddress().getAddressDirection(); cmDB.Parameters.Add('@address_street', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_street'].Value = person.getMailingAddress().getAddressStreet(); cmDB.Parameters.Add('@address_street_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_street_type'].Value = person.getMailingAddress().getAddressStreetType(); cmDB.Parameters.Add('@address_apt_number', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_apt_number'].Value = person.getMailingAddress().getAddressAptNum(); cmDB.Parameters.Add('@address_city', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_city'].Value = person.getMailingAddress().getAddressCity(); cmDB.Parameters.Add('@address_state', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_state'].Value = person.getMailingAddress().getAddressCity(); cmDB.Parameters.Add('@address_zipcode', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_zipcode'].Value = person.getMailingAddress().getAddressZipcode(); cmDB.Parameters.Add('@address_county', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@address_county'].Value = person.getMailingAddress().getAddressCounty(); cmDB.ExecuteNonQuery(); // insert Personal Info cmDB = new SqlCommand('sp_InsertPersonalInfo', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@birthdate', System.Data.SqlDbType.DateTime); cmDB.Parameters['@birthdate'].Value = person.getBirthdate(); cmDB.Parameters.Add('@gender', System.Data.SqlDbType.VarChar, 1); cmDB.Parameters['@gender'].Value = person.getGender(); cmDB.Parameters.Add('@ss_number', System.Data.SqlDbType.VarChar, 20); cmDB.Parameters['@ss_number'].Value = person.getSSNumber(); cmDB.Parameters.Add('@person_type', System.Data.SqlDbType.VarChar, 20); cmDB.Parameters['@person_type'].Value = person.getPersonType(); cmDB.Parameters.Add('@registration_date', System.Data.SqlDbType.DateTime); cmDB.Parameters['@registration_date'].Value = person.getRegistrationDate(); cmDB.Parameters.Add('@ip_address', System.Data.SqlDbType.VarChar, 20); cmDB.Parameters['@ip_address'].Value = person.getIPAddress(); cmDB.Parameters.Add('@browser_info', System.Data.SqlDbType.VarChar, 20); cmDB.Parameters['@browser_info'].Value = person.getBrowserInfo(); cmDB.Parameters.Add('@drivers_license', System.Data.SqlDbType.VarChar, 20); cmDB.Parameters['@drivers_license'].Value = person.getDriversLicense(); cmDB.ExecuteNonQuery(); //insert email address contact type cmDB = new SqlCommand('sp_InsertContactType', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@contact_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact_type'].Value = 'Email'; cmDB.Parameters.Add('@contact', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@gender'].Value = person.getEmailAddress(); cmDB.ExecuteNonQuery(); //insert secondary email address contact type cmDB = new SqlCommand('sp_InsertContactType', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@contact_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact_type'].Value = 'Secondary Email'; cmDB.Parameters.Add('@contact', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@gender'].Value = person.getSecondaryEmailAddress(); cmDB.ExecuteNonQuery(); //insert home phone contact type cmDB = new SqlCommand('sp_InsertContactType', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@contact_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact_type'].Value = 'Home Phone'; cmDB.Parameters.Add('@contact', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact'].Value = person.getHomePhone(); cmDB.ExecuteNonQuery(); //insert work phone contact type cmDB = new SqlCommand('sp_InsertContactType', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@contact_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact_type'].Value = 'Work Phone'; cmDB.Parameters.Add('@contact', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact'].Value = person.getWorkPhone(); cmDB.ExecuteNonQuery(); //insert cell phone contact type cmDB = new SqlCommand('sp_InsertContactType', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@contact_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact_type'].Value = 'Cell Phone'; cmDB.Parameters.Add('@contact', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact'].Value = person.getCellPhone(); cmDB.ExecuteNonQuery(); //insert cell phone contact type cmDB = new SqlCommand('sp_InsertContactType', cnDB); cmDB.Parameters.Add('@person_id', System.Data.SqlDbType.Int); cmDB.Parameters['@person_id'].Value = id; cmDB.Parameters.Add('@contact_type', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact_type'].Value = 'Fax Number'; cmDB.Parameters.Add('@contact', System.Data.SqlDbType.VarChar, 50); cmDB.Parameters['@contact'].Value = person.getFaxNumber(); cmDB.ExecuteNonQuery(); inserted = true; } catch (SqlException sqlEx) { throw new Exception(GetSqlExceptionMessage(sqlEx.Number)); } catch (Exception ex) { throw ex; } finally { if (cnDB.State == ConnectionState.Open) cnDB.Close(); } return inserted; }
Edit: I feel this code will be extremely hard to maintain later on. Can anyone help me figure out a more simple/maintainable way to do this? I’m also stumped on how i should go about updating a record after it has been added.
Thanks in advance for any help
First if you want to simplify maintaneance, I would look at using an ORM to do the mapping. I’d look at nHibernate, Linq2Sql, Entity Framework or one of the other billion or so out there. It will remove a lot of noise from above.
Second suggestion would be to continue the refactoring you were doing. I like how you absrtacted Address, if you look at your Person, a Person doesn’t have a previous name, what your doing is leaking a requirement to track previous information, within your domain model. I would move all of that out, and define a DTO, which would have two properties:
I think this cleans up a lot of the noise. I also like to handle the multiple phone numbers using a dictionary essentially we have:
Some people might make Phone have numerics, so I don’t want to debate that, or you could just have a single string like you do. One thing to keep in mind is Internaitonalization if this applies.
Now on my person I would have a Dictionary, this allows you then to break your four inserts into a single loop as you loop over the phone dictionary. I would use a simillar model if you have a billing or ship to address.
If you don’t go with an ORM, one way to help adhere to DRY with your sql params is simple. The following code is not meant to be compiled but just to show you a pattern to again minimize noise:
Now what you’ve done is consolidated so when you add a new property to a person you only have to modify one function when dealing with Parameters.
One more thing to insert your current and previous address, you are not being DRY. You could do this:
Now from your insert Person routine you would call this method twice:
Of course if you take my earlier suggestions this might look very different.
Edit
I totally missed this but I wanted to highlight what Chris said (and I +1 you but felt it was such a good thing I had to repeat it. Use Properties:-)