SDSU CS 596: Client-Server Programming
Spring Semester, 1997
Doc 16, States and Classes

To Lecture Notes Index
San Diego State University -- This page last updated Mar 13, 1997
----------

Contents of Doc 16, States and Classes


States and Classes slide # 1
...The Basic Idea slide # 2
...Strawman slide # 3
...CardboardMan Driver Program slide # 5
...Issue - The State of the States slide # 7
...SoggyCardboardMan NoAuth slide # 7
...TinMan NoAuth slide # 9
...Issue - How to create Just One Object slide # 11
The Picture slide # 12

Doc 16, States and Classes Slide # 1

States and Classes

An Example
SPOP

Example protocol: Simple Post Office Protocol (SPOP)

Command have the same functionality as POP but are limited to the following:


We have the following names for the states:



Doc 16, States and Classes Slide # 2

The Basic Idea





Each method (pass, user, etc.) performs the proper action for the given state and returns the next state

SPopState is abstract state with the default behavior for each method

Server is done with client when we reach the Quit state, so I did not add methods to that state


Doc 16, States and Classes Slide # 3

Strawman Driver Program

class SPopServer implements ServerEngine 
     {
     DataInputStream     input;
     PrintStream     output;
     
     // some stuff removed, see DateServer, Doc 10, slide 8

     public void run()
          {
          try
               {
               SPopState currentState = new NoAuth();
               do
                    {
                    String inputLine = input.readLine();
                    if ( inputLine.startsWith( "PASS" ) )
                         currentState = currentState.pass();

                    else if ( inputLine.startsWith( "USER" ) )
                         currentState = currentState.user();
                    etc.
                    
                    send response to client
                    }
               while ( ! currentState instanceof Quit  );
               input.close();
               output.close();
               }
          }     
     }


Doc 16, States and Classes Slide # 4
Issues

The methods of SPopState and child classes:

need arguments

need to return two values: next state and response to user

Solution

Pass in arguments

Let one argument be a response object, which state can modify by adding proper response


So create SPopResponse class!

What are the responsibilities of SPopResponse?


Doc 16, States and Classes Slide # 5

CardboardMan Driver Program

class SPopServer implements ServerEngine 
     {

     public void run()
          {
          try
               {
               SPopState currentState = new NoAuth();
               do
                    {
                    String inputLine = input.readLine();

                    SPopResponse answer = new SPopResponse();

                    if ( inputLine.startsWith( "PASS" ) )
                         currentState = currentState.pass( answer );

                    else if ( inputLine.startsWith( "USER" ) )
                         currentState = currentState.user( answer );
                    etc.
                    
                    output.println( answer );
                    }
               while ( ! currentState instanceof Quit  );
               input.close();
               output.close();
               }
          }     
     }

Doc 16, States and Classes Slide # 6
CardboardMan SPOPState

public class SPOPState {
     public SPOPState USER( other arguments,
                                        SPopResponse serverResponse     )
     {
          return defaultAction( serverResponse );
     }

     public SPOPState PASS( other arguments,
                              SPopResponse serverResponse     )
     {
          return defaultAction( serverResponse );
     }

     public SPOPState LIST( other arguments,
                                        SPopResponse serverResponse     )
     {
          return defaultAction( serverResponse );
     }

     private SPOPState defaultAction(          SPopResponse
                                    serverResponse )
     {
          serverResponse.error();
          return new Invalid();
     }
}


Doc 16, States and Classes Slide # 7

Issue - The State of the States

How do States get past Information?

The NoAuth state gets the user name

The HaveUser state gets the password

The HaveUser state needs the user name to verify password

But the PASS command from client does not contain user name


The Process state needs user name to get mail messages

SoggyCardboardMan NoAuth


public class NoAuth extends SPOPState
{

     public SPOPState user( some other arguments,
                                   SPopResponse serverResponse     )
     {
          serverResponse = new SPopResponse.ok();
          String userName = get userName from argument list;
          return new HaveUser( userName );
     }
}

Now HaveUser object has user name!

Doc 16, States and Classes Slide # 8
Problem with State having States?!
(Who is on first?)


Each client request can result in creating a new state object

If a large number of clients connect to a concurrent server at the same time, the creation of all the state objects can become a performance issue

Solution is to create one object per state class and reuse it

If the objects have data fields (data members) then two threads can not use the same object

Solution is to not allow the state classes to have any data fields

So where do we store the user name so other state objects can access it?

Solution is to create a class to store the data needed by all states

Call this class SPopData

What are the responsibilities of SPopData?


Doc 16, States and Classes Slide # 9

TinMan NoAuth


public class NoAuth extends SPOPState
     {

     public SPOPState user( some other arguments,SPopData
data,
                                   SPopResponse serverResponse     )
          {
          serverResponse = new SPopResponse.ok();
          String userName = get userName from argument list;
          data.setUserName( userName );
          return new HaveUser( );
          }
     }


Doc 16, States and Classes Slide # 10
TinMan SPopServer
class SPopServer implements ServerEngine 
     {

     public void run()
          {
          try
               {
               SPopState currentState = new NoAuth();
               SPopData clientData,
               do
                    {
                    String inputLine = input.readLine();

                    SPopResponse answer = new SPopResponse();

                    if ( inputLine.startsWith( "PASS" ) )
                         currentState = currentState.pass( clientData, answer );

                    else if ( inputLine.startsWith( "USER" ) )
                         currentState = currentState.user( clientData, answer );
                    etc.
                    
                    output.println( answer );
                    }
               while ( ! currentState instanceof Quit  );
               input.close();
               output.close();
               }
          }     
     }

Doc 16, States and Classes Slide # 11

Issue - How to create Just One Object


// Only one object of this class can be created
public class NoAuth extends SPOPState
     {
     private static NoAuth _instance = null;

     private NoAuth()     { }

     public static NoAuth getInstance()
          {
          if (  _instance == null )
                _instance = new NoAuth();
          return _instance;
          }

     public SPOPState user( some other arguments,SPopData data,
                                   SPopResponse serverResponse     )
          {
          serverResponse = new SPopResponse.ok();
          String userName = get userName from argument list;
          data.setUserName( userName );
          return new HaveUser( );
          }
     }

class Program
{
public void aMethod()
{
X = NoAuth.getInstance();
}
}

Doc 16, States and Classes Slide # 12

The Picture



Concurrent Server


Doc 16, States and Classes Slide # 13
The Interesting Questions

Who does the actual work?

checking the password and user name

getting the mail messages

Who does the mapping from strings to functions?


How does all this fit together?


Does anyone understand this?



Special Bonus Question

Can you determine how to eliminate the need for mapping from strings to functions without using if statement (or switch statements)?
----------