Monday, November 3, 2008

DueDates 1.1

We worked a lot on our DueDates project this week, adding functionality such as the ability to sort results by due date or library, and the ability to filter results to only items that are due within a specified number of days. This was a pretty easy week for me and Erin because we had already implemented support for the Hawaii State Public Library System previously. We finished most of the major coding relatively early in the week and spent the rest of the time tweaking the code and updating documentation.



Implementing the Sort Option

In the previous version of our system, our Library classes would format each item's information into a String and concatenate these Strings together to form the results for each library. In order to sort these results, we would have had to combine the result Strings for each library, parse this composite String into its component items, and then check each item's due date or library name. While all this is certainly doable, it is also unnecessarily messy and complicated. We decided to create a BorrowedItem class to store item information, and to return the results as a List of BorrowedItem objects. This way, we could take advantage of the Collection class's sort method by implementing different Comparators for different sort options.

The BorrowedItem class stores due dates as a String in the form 'YYYYMMDD' for easy comparison between dates; the due date Comparator can simply use the String.compareTo method to compare dates. After implementing the 'within' option (see below), we realized that we probably should have stored the due date as a Calendar object. We will probably do this next time. Actually, we could have created our own DueDates class that extends the Calendar class and "understands" many different date formats. However, given the size and scope of our current system, we saw no need for this, and decided to stick with the simplicity of Strings for now. We will probably revisit this issue later as our system evolves and grows.

Implementing the 'within' Option

The problem of filtering results to only those items due within a specified number of days basically reduces to the problem of comparing the due date with the current date.  In order to compare dates, we got the current date as a Calendar object; converted our due date String into a Calendar object (we could have saved ourselves this step if we had stored the due date as a Calendar object to begin with); converted both Calendars into milliseconds elapsed since the Unix epoch (January 1, 1970, 00:00:00); subtracted the two values; and then converted the difference into days.  I was really surprised that, even after Googling this problem, I couldn't find a more straightforward approach than subtracting milliseconds elapsed since the Unix epoch.

Continuous Integration

This week, we started using Hudson, a continuous integration tool. Continuous integration basically means that you have a process that automatically builds and tests your system whenever any member of the project commits to the code repository. Because everything is automated, it encourages project members to commit more often, so code is continuously being integrated, the system is more up-to-date, and the impacts of any changes are more visible. This helps ensure that the changes you made work with the rest of the system, including any changes that anyone else made. Additionally, any problems are quickly detected and can be resolved before there are many other changes to the system.

The Group Process

Erin and I streamlined our group process a bit this week, but for the most part we worked together in pretty much the same way. We got together every other day check-in on each other, discuss any issues that came up, and work together. Last time, we defined issues to work on as they came up; this week, we tried to lay out all the issues to work on beforehand. We then picked issues that we wanted to work on, and notified the other person. We didn't keep track of the issue owner in the issue tracker because this is a two-person project and it was more hassle than it was worth; if this project had involved more people, we would have made more of an effort to state each issue's owner.

Things to Think About

One problem we had was increasing the code coverage of our tests. We have quite a few methods that we didn't know how to write tests for because they are private. It didn't seem appropriate making these methods non-private just for testing purposes. We also couldn't test the HawaiiStateLibrary class properly because we didn't want to save the login credentials to the repository.

Another issue we pondered was how to make it easier for developers to extend our system. In the previous version of the system, if someone wanted to add their own library, all they would have to do is write a class that implements the Library interface and connects to their library's website; they didn't really have worry too much about the rest of the system. Now, however, they have to know how the BorrowedItem class works as well. Ideally, we would like to be able to make our system so that outside developers can extend it without having to worry too much about the implementation details of our system.

No comments: