README for hw4, cscie247,  Russell Lowke  November 30th 2003.


Design and Implementation choices for Distress, hw4.



I've tried to keep to the Bill Robinson Assignment 2 solution as closely as possible.

Distress is a "singleton" pattern called by DistressDriver and DistressWriter, both of which are in their own asn4 package.  All the distress package objects communicate through the single Distress class, and, as such, it is an example of a "facade" pattern.

Distress, Consumer, Realtor, Lender and MultiFamily classes all implement add(), remove(), and list() methods that take an Object as a parameter and throw an exception.  Their function is to manipulate their ArrayList that contains a list of stored objects.  In the case of Distress, User objects are stored; Consumer, PropertyProfile objects; Realtor, Property objects; Lender, MortgageOffering objects; and Multifamily, MFUnit objects.  Although MFUnit does not require adding and removing its objects as frequently as the others, it does require such functionality, and thus uses the same type of implementation.

PropertyProfile, Property and MortgageOffering objects all need a reference to the User who created them.  This reference is stored in the field mObjContainer.  It is essential that when these objects are created their "container" or creating User is passed to them in the constructor, then the object may be safely added to that Users list via type Users add() method.  In the same vein, Property and MortageOffering objects have a obtainEmail() method that allows a user to obtain the e-mail of the objects container/owner.

There are four match() methods.  One in the parent class Property, and one of each of the child classes, MultiFamily, SingleFamily, and Condominium.  The child versions override the parent allowing for comparisons of their fields, then they use super.compare() to call the parent allowing the parent to then check for its own matches.  The parent (Property) also has its own match() method as it has been declared in the spec. as NOT being abstract, and therefore could have instances without child objects.

The match() method iterates through the SearchItems passed to it inside the SearchCriteria object. These SearchItems are not "pairs" but "triplets," -- a key and two values.  One value represents a minimum possible, the other a maximum.  This allows ranges to be taken care of.  In the case of comparisons the third value is left as null, and only the first value is checked. match() simply calls upon a compare() method for each SearchItem.

The compare() method decodes the variable key String sent to it, determining if the variable to be tested is a comparison or a range and if the test is an int, double, Date, String, or Object. It knows which test type to call according to the variable name, and simply invokes the appropriate test.  A true or false is returned signifying a passed or failed match for that SearchItem.

All of the packaging for searches is handled by the SearchCriteria object.  To create a search, create a new instance of SearchCriteria, then send it "add" commands to add SearchItems.  There are six (6) types of add. Three of these deal with comparisons, requiring two values (key-value pair), while the other three take ranges (key-max-min).  The three types dealt with are Integers, Doubles, and Objects.  Objects handle all object types such as Date, String and Enum types.

SearchCriteria is used for both MortageOffering searches and Property searches.  There are two additional boolean values in SearchCriteria, pHasPropertyType and pHasCityStateZip.  When a SearchItem is added it is checked to see if it is a search for "propertyType" or "cityStateZip".  If so, the corresponding flag is tagged true.  When a Property search is attempted these flags are checked, and if either are false the search is rejected.

I have five enumeration types, these are TypeUser, TypePurchasingTF, TypeProperty, TypeParking, and TypeMortgage.  The "Type" is used as a prefix rather than a suffix so that the classes appear in the directory together.  These enumeration are of the "public static final TypeMortgage FIXEDRATE = new TypeMortgage()" form rather than the "public static final int FIXEDRATE = 1" form.

Distress has public helper functions listProperties(), listMortgageOfferings(), and listPropertyProfiles() that traverse lists owned by Users. A new new ArrayList of the desired type is constructed.  These functions are of great help to the DistressWriter when it needs to dump lists of Property, Mortgage or PropertyProfile.

I am not developing on a Windows machine, rather Unix, and am using .bat files in the form
suggested by ggimler on the Bulletin board.  He suggests the following method to trigger .bat from Unix

to run on unix:
/bin/sh compile.bat
/bin/sh run.bat

My .bat files work fine in Unix using these commands.


I hope this readme clarifies my design somewhat, regardless, I think you will find the code itself to be reasonably clear.





Russell Lowke