Design Pattern: Treating Objects as Descriptors

April 19th, 2007

I think frequently about the design of software while I drive between home and work. I frequently come across the problem of designing user-defined, compound types or classes. Determining a compound type’s member fields and methods requires a lot of effort. The problem’s complexity is increased when an instance of a class consists of fields drawn from multiple tables in a database. Designing a class that is used in a web application is made more complicated by the stateless nature between each request of a browser. The general problem is stated as designing a class that draws information from multiple sources and supports class instances with short lifetimes.

In practice, determining the interface of an object is difficult. The use of “accessors” and “modifiers,” functions that access and modify an object’s state or internal data, is common practice among software engineers. The use of these functions helps control the operations that can be performed on an object, and it it helps maintain consistency in an object’s state. It also allows the internal implementation of a class to be modified without affecting the code that operates on instances of the class. There may be problems, however, with the tying functions and data into classes too tightly.

An example of an original Person class design is presented below with several interface functions.


class Person
{
	private Name m_name;
	private Date m_birthdate;
	private String m_password;

	public function SetName( Name name );
	public function GetName();
	public function SetBirthdate( Date date );
	public function GetBirthdate();
	public function SetPassword( String password );
	public function GetPassword();
}

The m_password field of the Person object may be retrieved from a database table named User_Passwords while the other information is fetched from the User_Pedrigree table. In the example system, code that accesses or modifies user passwords is spread throughout the system, but execution of the code is infrequent. Although the password information may be used in only 5% of operations that deal with Person object, because the object’s consistency is maintained, the password is always retrieved. With this interface, “person->GetPassword()” and “person->SetPassword( new_password )” may be in multiple places of the code.

Assuming that retrieving the password information is later found to be an expensive operation and that expense is paid every time a Person object is created, a couple of modifications to the operations on the class may be used to improve system performance. The underlying operation of retrieving a password can be reworked, or the password information can be separated from the type definition. Two refactorings of the Person object are presented below. The first treats the object as a descriptor to a function. The second refactoring reimplements the class to delay the retrieval of the password information.

Separating the password information from the Person object may force the removal of the GetPassword() and SetPassword() functions, and this will further require updates to code that rely on these functions. The need would have been avoided, if these interface functions were not present in the original class and independent functions were implemented to provide the same functionality. Code that operated on Person objects would appear as “GetPassword( person )” and “SetPassword( person, new_password )” instead of “person->GetPassword()” and “person->SetPassword( new_password )” as mentioned above.

Separating the password functions from the class is problematic, because it is against the goal of tightly grouping data and functions with classes. The code becomes less cohesive with this approach.

Delaying the retrieval of password information until it is first requested improves the example system’s performance. Resources are not used to retrieve password information, until it is first used. This has the benefit of allowing the object’s state to continue appearing consistent, and it allows code to continue enjoying the benefit of using classes to group functions and data.

The second option described above appears to be the better solution that addresses the example problem. Considering the first option may still be desirable in cases such as when the degree of cohesion between the class and its member data is unstable.

The Move to CentOS

April 15th, 2007

centoslogo-transparent.pngI decided to make the move this weekend. Witnessing Kelly adopt GNU/Linux after being a long-time user of Microsoft solutions inspired me to transition away from Microsoft Windows. So, I bought an open-box 500GB Seagate FreeAgent external hard drive from Fry’s Electronics for 140USD, moved all my data files from my Windows desktop, and converted my desktop to one that runs CentOS 5.0.

The computers in my home currently run Mac OS X on a Mac Mini, CentOS 4.4 on an old PII 400MHz, CentOS 5.0 on a P4 2.6GHz, and Microsoft Windows XP Pro on a Dell Inspiron 8600 laptop with a Pentium M 2.0GHz processor. I was thinking about trying out Ubuntu, but after hearing that it was derived from Debian, I decided to stick with a distribution based on RedHat Enterprise Linux.

Million Miles from Home

April 14th, 2007

John Johnson Jr. of the LA Times reports that NASA investigators narrowed down the loss of the Mars Global Surveyor to a bad command sent to the wrong address. Johnson also reports, “The review also said the spacecraft’s onboard fault protection system failed to respond to the errors.”

Surely, NASA could afford to run through the procedure of sending the command on a simulation.

from The Departed
Police Camera Tech: Who the fuck are you?
Dignam: I’m the guy who does his job. You must be the other guy.

John Backus, 82, Computer Sci Legend

March 21st, 2007

The New York Times has posted an obituary for John Backus. All recent computer science graduates have been exposed to John Backus’ work with BNFs, making him a legend like Djiskstra. John Backus makes up the Backus in the Backus-Naur duo. I admit that I did not remember Backus as the creator of Fortran, but the article discusses the importance of his Fortran work, which introduced new methods to make working with machines easier for people.

I find myself trying to make it easier for hardware engineers to work with a software interface. Here’s a description of a programming language in Backus-Naur form that I just wrote up:

statement ::= variable_declaration “;” | expression “;”

variable_declaration := type variable_name | type assignment

expression ::= addition | subtraction | assignment | operand

assignment ::= variable_name “=” expression

addition ::= expression “+” expression

subtraction ::= expression “-” expression

operand ::= numeric_constant | variable_name

Eight Ball in the Side Pocket

March 15th, 2007

Poor scheduling has been the bane of several projects with which I have had involvement. Ever since the one-month estimate that I gave for my first independent software development project, a shopping cart, a statement by Fred Brooks resonates continually in my mind. In The Mythical Man-Month, Brooks states, “More software projects have gone awry for lack of calendar time than for all other causes combined.” There are many things that are detrimental to projects, and Brooks suggests that the lack of time is the most significant factor that hampers a project and overshadows the total damage inflicted by all others.

Having learned and relearned the importance of good reality-based scheduling, I become squeamish when receiving a seemingly groundless estimate on project duration. In particular, I am very pessimistic about schedules that call for an entire project to be completed within a month. Conceptualization of a nontrivial system can easily exceed two weeks. Design will most likely require more than a week. This leaves implementation and testing with less than a week in a one-month schedule.

Two approximations to a feasible solution for the software procurement problem with a constraint of one month are the minimization of the product feature set and the minimization of system quality. These have served as candidates, though with strong resistance from project members, in the past. Betting against optimistic or baseless schedules is betting with the house.