System Sort Usage:

advertisement
System Sort
Usage:
The System Sort program can be run in two different modes – text based and through a
GUI. The text version takes its input through standard in, so it should be run as follows:
java SortMain [-r | -f # | -c # | -i | -n]
< examplefile.txt
To run the GUI version of the program use:
java SortMain –g
The GUI version has a button that allows you to browse for the text file you would like to
use as input. Choose your options, then click the “sort” button. Much like the command
line version, this can only be run (sorted) once, then the program must be exited. The
GUI mainly is to demonstrate the Decorator Pattern, not to be used as a viable software
package.
Basic Organization:
The data is pulled in from either standard input or a text file (as explained above).
The data is brought in with the Input class. This input class stores all of the lines in a
character buffer. We then create and Access_Table that holds LinePtrs. The members of
the LinePtrs class are just integers indicating how far into the character buffer a line or
field starts. This is our workaround for not being able to set aside an exact place in
memory and use pointers to it as we would in C++.
The Access_Table is masked beneath the Sort_AT_Adapter to allow the sort to
use its own standard functions without knowledge of how the AccessTable works.
Comparison operators are a good example of the types of functions in the adapter class
that allows the interface between SystemSort and Access_Table.
The SystemSort and Options objects have single instantiations. The Options
object holds the user specified options and the root compare function.
The Sort is done as a QuickSort. This quicksort will sort any objects implemented
from the “Sortable” interface. So we caused our LinePtrs to implement Sortable and
define the virtual function from Sortable for comparison.
Classes:
SortMain – the main program
SortGUI – the graphical user interface for SortMain
DArray – a dynamic array
Input – class for reading in data from stream or file
LinePtrs – pointers into a memory buffer
Options – global user options used for the program
Sort – abstract class for ordering methods
QuickSort – efficient sorting method
Pivot- pivot choosing strategy
PivotLast – chooses the last element in the array past to it
Access_Table – holds a DArray of LinePtrs, and the data buffer
Sort_AT_Adapter – wrapper to adapt Access_Table to the Sort
Sortable – object that can be sorted
SystemSort - main system object
Pattern Usage:
Façade
The best representation of the Façade pattern is use of the .print() function. The access
table is hidden so that the user doesn’t have to do the job of going through the access
table and LinePtrs to print individual lines. Instead, print masks the task behind the easier
to user print() function. The Façade Pattern is meant to be used to hide complex details
by giving a higher-level interface, which is exactly what happens here.
Adapter Pattern
The Adapter Pattern is used extensively to allow classes to interface with one another
where they otherwise could not. The intent of the Sort_AT_Adapter pattern is to allow
the calls that Sort intends to use (such as compare()) to be translated into the calls that the
Access_Table class uses. This was explained extensively in the previous homework
assignment.
Another good example is the “toString” function in many of the classes. For example, we
can call:
System.out.println(SystemSort->instance());
The instance of SystemSort can be printed because the toString function is overloaded to
call the toString on the Sort_AT_Adapter, and so on, until we reach the table where we
can access the data and return the appropriate string. The access table is hidden behind a
simple print call to a SystemSort object.
We used this yet again in the QuickSort class to allow it to sort anything of type
“Sortable”. This way the QuickSort did not need to know that is was sorting LinePtrs,
because the Sortable interface was extended by LinePtrs.
Singleton
The Singleton pattern is meant to force a single instance of classes that we use globally.
The SystemSort and Options classes have an instance() method that returns the one and
only instance of these classes. The first call to instance will create this object (which has
a static member), and subsequent calls make use of this object and will not allow further
instantiations. See observations for more information.
Strategy
The strategy pattern defines a family of algorithms, encapsulates each one, and makes
them interchangeable. Strategy lets the algorithm vary independently from clients that use
it. The QuickSort class implements a Pivot class that chooses a pivot for the given array
in the quicksort algoritihim. This class can be replaced with any method for finding a
pivot. Currently we are using the PivotLast class as our strategy.
Double-Checked Locking Optimization Pattern
This pattern was not used here, because java inherently made it unnecessary. The
Singleton objects are already capable of preventing any race condition problems. See
observations for more information.
Decorator Pattern
This was our additional pattern that we applied to the SystemSort program. The
Decorator Pattern’s purpose is to attach additional responsibilities to an object
dynamically and to provide a flexible alternative to subclassing for extending
functionality. Our GUI lets you choose different input files, and more importantly
different options flexibly while the program is running. The use can actually see the input
file in the text area, and then can make decisions as to which fields/columns will be
sorted and in what fashion.
Bridge Pattern
In the C code, the “<” operator was overloaded for LinePtr objects. Actually, one set of
code used comparison between LinePtr objects directly, where the other set used the
compare function with actual pointers to places in memory. In our code, we had the
compare function in the Options class, and we passed the compare on to strings created
from the locations we passed to compare(). That is, we passed the integers that indicated
where in the char buffer each field started to compare(). Compare constructed strings
from these characters and called an appropriate function to compare the strings based on
which options the user chose. So the comparison is different depending on options, but it
does so by adapting to another comparison function.
Factory
We took out the factory pattern, generally, because it would have required dynamic
binding, which would have been much slower. The C++ code actually redefined the
compare function to completely turn it into another function. We did something more
along the lines of the Bridge and Adapter patterns by passing on the comparison to
different functions depending on user options.
Observations
Java made the implementation of some classes easier than corresponding C++ classes.
For instance C++ requires lazy instantiation for variables when doing the singleton
pattern. In Java we can create data members as static final. Java is sure to instantiate this
when the class is created. Therefore the double-checked locking optimization is also not
required because there is no race condition. SystemSort.java has examples of where this
happens in the source code.
Class Diagram:
Download