SDSU CS 596: Client-Server Programming
Spring Semester, 1997
Doc 2 Pipes and Hinges

To Lecture Notes Index
San Diego State University -- This page last updated Jan 29, 1997
----------

Contents of Doc 2 Pipes and Hinges


References slide # 1

Pipes slide # 2
Hinges slide # 3

Some Hinge Oil slide # 8



Doc 2 Pipes and Hinges Slide # 1

References


Pree, Design Patterns for Object-Oriented Software Development, Addison-Wesley, 1995
Doc 2 Pipes and Hinges Slide # 2

Pipes



This is not a pipe
Doc 2 Pipes and Hinges Slide # 3

Hinges


Software is not arbitarily adaptible

One can not modify existing software arbitarily


Software has designated places where it is designed to change

These spots can be though of as hinges or hot spots


Changes at one of these hinges is relatively easy

Changing software in other locations or ways tends to:

break the system

be expensive

Force

Designing hinges into a program makes the program easier to modify

Counter-Force
There is a cost to building hinges

Too many hinges can make the software expensive and hard to understand

Doc 2 Pipes and Hinges Slide # 4
Hinge Example - Constants

Program that uses course numbers

class Example extends Frame 
     {
     public Example()
          {
          setTitle( "Hinge Example" );
          resize( 100, 100 );
          setLayout( new FlowLayout() );
          add( new Button( "CS 596") );
          show();
          }
     
     public boolean action( Event processNow, Object buttonPressed )
          {
          if ( buttonPressed.equals( "CS 596" ) )
               System.out.println("Pressed");
          return true;
          }
     }



Doc 2 Pipes and Hinges Slide # 5
First Hinge

class Example extends Frame 
     {
     
     String courseName = "CS 596";
     
     public Example()
          {
          setTitle( "Hinge Example" );
          resize( 100, 100 );
          setLayout( new FlowLayout() );
          add( new Button( courseName ) );
          show();
          }
     
     public boolean action( Event processNow, Object buttonPressed )
          {
          if ( buttonPressed.equals( courseName ) )
               System.out.println("Pressed");
          return true;
          }           
     }

Doc 2 Pipes and Hinges Slide # 6
Another Hinge

class Example extends Frame 
     {
     String courseName;
     
     public Example()
          {
          try
               {
               ASCIIInputStream  cin = 
                    new ASCIIInputStream( 
                       new BufferedInputStream (
                          new FileInputStream( "ExampleConfig" )) );

               courseName = cin.readWord() + cin.readWord();
               
               setTitle( "Hinge Example" );    resize( 100, 100 );
               setLayout( new FlowLayout() );
               add( new Button( courseName ) );
               show();
               }
          catch ( FileNotFoundException noFile )
               { System.out.println( "No Config file"); }
          catch ( IOException readError )
               { System.out.println( "Read Error"); }     
          }
     
     public boolean action( Event processNow, Object buttonPressed )
          //Same as before
}


Doc 2 Pipes and Hinges Slide # 7
ExampleConfig Contents

CS 569


This is a Hinge?

How safe?

How extendable?




Doc 2 Pipes and Hinges Slide # 8

Some Hinge Oil

sdsu.util.LabeledData

Subclass of Hashtable and Property with added features of:

Parsing

Converts itself to and from strings

Read strings and streams

Allows whitespace and comments in strings representation

Automatically quotes special characters

User can define whitespace, separators, and quote characters
Command Line

Parses command line flags

Flag syntax

-flag=value
-flag value
-flag
--xyz
--

Default values

Permits declaring default values

Doc 2 Pipes and Hinges Slide # 9
Simple Example of LabeledData

class LabeledDataExample
     {
     public static void main( String[] arguments)
          {
          LabeledData defaults = new LabeledData();
          defaults.put( "instructor", "Roger Whitney" );
          defaults.put( "courseName", "CS108" );
          
          String serialized = defaults.toString();     
          System.out.println( serialized );
          
          LabeledData refried = new LabeledData( );
          refried.fromString( serialized );
          System.out.println( refried.getData("courseName" ) );
          System.out.println( refried.getData("instructor" ) );
          
          OutputStream  cout;
          cout = new BufferedOutputStream ( 
                         new FileOutputStream( "test" ) );
          refried.save( cout );
          }
     }
Output
instructor='Roger Whitney';courseName=CS108
CS108
Roger Whitney
File "test"
#Sample
#Sat Jan 18 19:22:54 1997
instructor='Roger Whitney';courseName=CS108
Doc 2 Pipes and Hinges Slide # 10
File Example of LabeledData

DataFile
# a comment, goes to the end of the line

instructor = 'Roger Whitney';      # 's are used keep name one string
courseName = 'CS 596';
courseLocation = ba254          # ; is a separator, not a terminator


Program
public static void main( String[] arguments )
     {
     try
          {
          InputStream  cin = new BufferedInputStream (
                    new FileInputStream( "ExampleConfig" ) );
          LabeledData config = new LabeledData();
          config.load( cin );
          System.out.println( config.getData("courseName" ));
          System.out.println( config.getData("instructor" ));
          }
     catch ( IOException readError )
          {
          System.out.println( readError );
          }
     }

Output
CS 596
Roger Whitney

Doc 2 Pipes and Hinges Slide # 11
Third Hinge Example

class Example extends Frame 
     {
     String courseName;
     
     public Example()
          {
          LabeledData settings = readConfigFile();
          courseName = settings.getData( "courseName" );
          
          setTitle( "Hinge Example" );
          resize( 100, 100 );
          setLayout( new FlowLayout() );
          add( new Button( courseName ) );
          show();
          }
          

     public boolean action( Event processNow, Object buttonPressed )
          {
          if ( buttonPressed.equals( courseName ) )
               System.out.println("Pressed");
          return true;
          }           


Doc 2 Pipes and Hinges Slide # 12
Third Hinge Example Continued

public LabeledData readConfigFile()
          {
          try
               {
               InputStream  cin = new BufferedInputStream (
                         new FileInputStream( "ExampleConfig" ) );
               LabeledData config = new LabeledData();
               config.load( cin );
               return config;
               }

          catch ( FileNotFoundException noFile )
               { 
               System.out.println( "No Config file");
               }

          catch ( IOException readError )
               { 
               System.out.println( "Read Error");
               }     
          }
     }// end class

Doc 2 Pipes and Hinges Slide # 13
Third Hinge Example
Pros

Flexible and relatively safe file format

Labels on data:

aid human reader
help insure proper reading of data

Other?


Cons

Is config file given in relative or absolute path?

If absolute, multiple users cause problems

If relative, calling from different directorys is a problem

Others?



Need a better hinge


Doc 2 Pipes and Hinges Slide # 14
Command Line Arguments & LabeledData
Program

class LabeledDataExample
     {
     public static void main( String[] arguments)
          {
          LabeledData config = new LabeledData();
          config.fromCommandLine( arguments );
          System.out.println( config.getData("courseName" ));
          }
     }

Command Line

java LabeledDataExample -courseName=CS596 -instructor Whitney


Output
CS596
Flag Options
- flag=value- flag value- flag (for last argument or next argument starts with - )-- zyx (individual characters become separate flags)-- (ignore rest of the arguments) Flags with no values are given value of LabeledData.NO_VALUE Which is the string "_NO_VALUE"
Doc 2 Pipes and Hinges Slide # 15
Default Values & LabeledData
Program

class LabeledDataExample
     {
     public static void main( String[] arguments)
          {
          LabeledData config = new LabeledData();
          config.fromCommandLine( arguments );
          String name = config.getData("courseName", "CS108" );
          System.out.println( name );
          }
     }

Command Line

java LabeledDataExample   -instructor Whitney


Output
CS108


getData

getData( key, defaultValue )

If the hashtable does not contain "key", then getData returns "defaultValue"


Doc 2 Pipes and Hinges Slide # 16
More Default Values & LabeledData
Program

class LabeledDataExample
     {
     public static void main( String[] arguments)
          {
          LabeledData defaults = new LabeledData();
          defaults.put( "instructor", "Roger Whitney" );
          defaults.put( "courseName", "CS108" );
          
          LabeledData config = new LabeledData( defaults );
          config.fromCommandLine( arguments );
          System.out.println( config.getData( "courseName" ) );
          System.out.println( config.getData( "instructor" ) );
          }
     }

Command Line

java LabeledDataExample -courseName CS596

Output
CS596
Roger Whitney

Default LabeledData

/* Constructs a new, empty labeledData object with the specified 
* default values.
*/
public LabeledData( LabeledData defaultValues )
Doc 2 Pipes and Hinges Slide # 17
Fourth Hinge Example

class Example extends Frame 
     {
     String courseName;
     
     public static void main(  String[] arguments )
          {
          new Example( getProgramParameters( arguments ) );
          }
          
     public Example( LabeledData settings )
          {
          courseName = settings.getData( "courseName" );
          
          setTitle( "Hinge Example" );
          resize( 100, 100 );
          setLayout( new FlowLayout() );
          add( new Button( courseName ) );
          show();
          }
          
     public boolean action( Event processNow, Object buttonPressed )
          {
          if ( buttonPressed.equals( courseName ) )
               System.out.println("Pressed");
          return true;
          }           

     
Doc 2 Pipes and Hinges Slide # 18
Fourth Hinge Example Continued

     public static LabeledData getProgramParameters( 
                                             String[] arguments )
          {
          LabeledData defaults = new LabeledData();
          LabeledData configFile = new LabeledData( defaults );     
          LabeledData parameters = new LabeledData( configFile );
          
          defaults.put( "configFile", "ExampleConfig");
          defaults.put( "courseName", "CS 596");

          paramaters.fromCommandLine( arguments );
          try
               {
               String fileName = parameters.getData( "configFile" );
               InputStream  cin;
               cin = new BufferedInputStream ( 
                         new FileInputStream( fileName ) );
               
               configFile.load( cin );
               }
          catch ( FileNotFoundException noFile )
               { 
               System.out.println( "No Config file");
               }
          catch ( IOException readError )
               { 
               System.out.println( "Read Error");
               }
          return parameters;     
          }
     }
Doc 2 Pipes and Hinges Slide # 19
How About This?
class Example extends Frame 
     {
     String courseName;
     
     static String courseNameFlag = "courseName";
     static String configFileFlag = "configFile";
     static String windowTitleFlag = "windowTitle";
     static String windowWidthFlag = "windowWidth";
     static String windowHeightFlag = "windowHeight";
          
     public static void main(  String[] arguments )
          {
          new Example( getProgramParameters( arguments ) );
          }
          
     public Example( LabeledData settings )
          {
          setTitle( settings.getData( windowTitleFlag ));

          int width = Integer.parseInt( settings.getData(
                                              windowWidthFlag ) );
          int height = Integer.parseInt( settings.getData(
                                              windowHeightFlag ) );     

          resize( width, height );
          setLayout( new FlowLayout() );
          
          courseName = settings.getData( courseNameFlag );
          add( new Button( courseName ) );
          show();
          }
Doc 2 Pipes and Hinges Slide # 20
Continued
     public boolean action( Event processNow, Object buttonPressed )
          {
          if ( buttonPressed.equals( courseName ) )
               System.out.println("Pressed");
          return true;
          }           

     public static LabeledData getProgramParameters( 
                                             String[] arguments ){
          LabeledData defaults = new LabeledData();
          LabeledData configFile = new LabeledData( defaults );     
          LabeledData paramaters = new LabeledData( configFile );
          
          defaults.put( configFileFlag, "ExampleConfig");
          defaults.put( courseNameFlag, "CS 596");

          paramaters.fromCommandLine( arguments );
          try
               {
               String fileName = paramaters.getData( configFileFlag );
               InputStream  cin;
               cin = new BufferedInputStream ( new FileInputStream(
                                                        fileName ) );
               configFile.load( cin );
               }
          catch ( FileNotFoundException noFile )
               { System.out.println( "No Config file"); }
          catch ( IOException readError )
               { System.out.println( "Read Error"); }
          return paramaters;     
          }
     }

Doc 2 Pipes and Hinges Slide # 21
Hinges

Force
Designing hinges into a program makes the program easier to modify

Counter-Force
There is a cost to building hinges

Too many hinges can make the software expensive and hard to understand
Original Program

class Example extends Frame 
     {
     public Example()
          {
          setTitle( "Hinge Example" );
          resize( 100, 100 );
          setLayout( new FlowLayout() );
          add( new Button( "CS 596") );
          show();
          }
     
     public boolean action( Event processNow, Object buttonPressed )
          {
          if ( buttonPressed.equals( "CS 596" ) )
               System.out.println("Pressed");
          return true;
          }
     }

Doc 2 Pipes and Hinges Slide # 22
Issues

Pipes and Hinges

The answer is finding the best balance between force and counter force

The balance between force and counter-force in school is off scale compaired to "real life", it is all counter-force



----------