Improving art of programming
hi guys, how do you guys deal with, say, a user table with 10 fields. all web pages are done, all business logic are done, interface classes properties are done etc.... then suddenly, the client wants another 10 fields. just add more columns to the tables and more properties in the classes?
this project im working on faces this problem. tables starting with 10 fields, now it's uncommon to see them having 50 fields.
I started to get interested with programming ideas, abstraction, composition, generics, functional programming. really change my way of "thinking" about programming. How do you guys solve such design issues? Any good books out there to read to make me into a better programmer? I'm the kind of programmer who wants to know "Why", instead of "what" and "how".
any advice/thoughts are greatly appreciated
Are you asking how to handle scope creep? Or is it more a question of database design?
It's really difficult to say without specifics.
Tables that are getting up toward 50 fields can and should probably be refactored and normalized as it's relatively unusual to see that many columns and for there be no way to break it down further. If you're seeing a lot of repeated columns of data on different rows, that's one good hint that something needs to get broken out; if you're seeing where each row only uses 20 of those 50 columns, that's another good hint. If you're seeing that there are different conceptual entities in a single row (there's a group of columns that specify the customer and a group that specify details for the order placed by that customer, for instance) then you should definitely be reconsidering things.
That all said, it's not impossible that 50 is what you need, but you're right to wonder if there's something to do about it.
This is the general rule of thumb I use:
Like CodeWhisperer said, if you find the additional fields being unused much of the time, it might be best to move those columns to another table, even if there is still only a one-to-one relationship between them.
User tables are especially prone to this because users represent people, and people tend to want to know as many details about each other as possible.
The first way I approach a user is to separate the core concepts that define not just a user, but the person behind the user. When I think of the term 'user', I tend to limit the properties to those pertaining to the authentication and permissions of the person logging in, and no other details. So, that's "username", "password" at the very least. If you have roles, you can add that column in as well. If you have a more granular, customized approach to permissions where each user might even have a unique set of permissions that are explicitly defined, then you definitely should itemize each permission in its own table and many-to-many that sucker to the user table with a mapping table.
Next, in most applications, a person is associated with some simple identification: Depending on whether this is a social media site, a corporate intranet, or whatever, the minimal columns that are used would be "firstName", and "lastName". Obviously, other columns may go in here as well, such as gender, title, displayName, and so forth. I usually put this into a "profile" table. Now, yes, users and profiles are almost certainly one-to-one tables, but the idea here is because a user is a "login" concept and a profile is more of a "display" concept we are separating the data out this way the same way you likely are doing in your code.
Contact info is often tricky. If you only have a single contact per profile (one street address, one email address, and one phone number) it might be reasonable to add that to the profile. Even if there's a primary/secondary emails and phone numbers, for the sake of simplicity, you might want to also add that to the profile. As soon as it gets more complicated than that, however, such as if you allow people to add arbitrary amounts of contact info, you absolutely need to factor that out into a ContactInfo table that might have "title", "phoneNumber", "emailAddress", "street1", "street2", "city", "state", "zip". ContactInfo gets especially hairy when you're dealing with internationalization, but that's for another day.
After that, you might have user preferences. Like individual permissions, preferences should be itemized in its own preference table, and there should be a user-to-preference-to-value table binding the two together.
Generally speaking, that should cover most everything. Bio's and other stuff might go into the profile, although depending on the database, some prefer to keep bios and other freeform columns in their own tables for optimization purposes.
Hopefully this answers your question. I don't know how your database is set up, of course, so I can't give you specific tips, but if you notice you've got columns specifically dealing with permissions like "canWrite", "canApprove", those should be factored out as aforementioned, and columns like "notifyBySecondaryEmail" and "phoneNumber42" should certainly be factored out appropriately.
Any good books out there to read to make me into a better programmer?
The quintessential books would be code complete and the pragmatic programmer. I also liked head first: design patterns.
All three are very mutch about the meta aspects of programming and not the how aspects of programming.
head first: design patterns
+1 good book.