The Basic Objects A Socket-Based Printer Server

3.2 The Basic Objects

Its often useful to start the process of designing a distributed application by pretending it is a single-machine application. Doing this allows architects to focus on finding the domain objects first. [ 2] Once the domain objects have been discovered, and their roles have been defined, the distributed infrastructure can be built around them. [ 2] Domain objects is a very loose and nebulous term. Roughly speaking, domain objects are classes that represent end-user ideas and abstractions. For example, a class named AccountEntry is probably a domain object, whereas a class named NetworkFlowControlBuffer probably isnt. In this case, well start with a very simple interface for our abstract notion of Printer : public interface Printer extends PrinterConstants { public boolean printerAvailable ; public boolean printDocumentDocumentDescription document throws PrinterException; } Our goal is to take a concrete implementation of the Printer interface [ 3] and make it available over the network. [ 3] We wont actually connect to a printer. While its a fun weekend project to wrap an existing printer driver such as the limited one presented in the java.awt.print package, doing so is beyond the scope of this book. Instead, well just use a very simple implementation called NullPrinter . This definition of Printer relies on two additional classes: DocumentDescription and PrinterException . These are both fairly simple classes, designed more to encapsulate related pieces of information than to implement complex behavior. The definition of DocumentDescription begins with five state variables that encapsulate the print request: public class DocumentDescription { public static final int FAST_PRINTING = 0; public static final int HIGH_QUALITY_PRINTING = 1; public static final int POSTSCRIPT = 0; public static final int PDF = 1; private DataInputStream _actualDocument; private int _documentType; private boolean _printTwoSided; private int _printQuality; private int _length; The only interesting aspect of this is the decision to use Stream to represent the actual document, rather than storing just a filename. Doing this makes the implementation of the printer server much simpler for two reasons: • There is no guarantee that the machine the server is running on has access to the same files as the machine running the client program. • If we just use the filename, and the file is edited before the actual printout occurs, we wont accurately reflect the users request. Using streams in the interface also makes it possible for us to print things other than files. For example, we can print the contents of a JTextArea by calling getText on the J TextArea , wrapping the resulting instance of String in a J TextArea , wrapping the resulting instance of String in a StringBufferInputStream , and passing that to the printer. PrinterException is a similar class. Its a custom exception that holds two pieces of information: how many pages were actually printed and a description of what went wrong with the printer: public class PrinterException extends Exception { private int _numberOfPagesPrinted; private String _humanReadableErrorDescription; }

3.3 The Protocol