State


Definition

An object's behavior change is represented by its member classes, which share the same super class.

Where to use & benefits

Example

To show the concept of State pattern, we use a simple command line program. If a GUI program is used, a mediator pattern or a flyweight pattern may be applied on it.

Users connect to a database to do some jobs. Users from Management department may focus on management. Users from Sales department may focus on sales information. Every connection has to perform similar functions like open, log and close. Suppose we have an abstract Connection class and have these functions listed. Thus, every subclass of Connection must implement these functions. We list three subclasses Management, Sales and Accounting for example, just to show the State pattern concept. The Controller class contains each state of connection. Its behavior is decided by another object, which is a Test class. All the details have been hidden from the Test class. Suppose we have a server which is a singleton. Which connection is made depends on the user. We use a Test class which makes a trigger from command line. In the real program, the trigger should be made by the user.

The following is a skeleton program.

abstract class Connection {
   public abstract void open();
   public abstract void close();
   public abstract void log();
}
class Accounting extends Connection {
   public void open() {
      System.out.println("open database for accounting");
   }
   public void close() {
      System.out.println("close the database");
   }
   public void log() {
      System.out.println("log activities");
   }
   //...
}
class Sales extends Connection {
   public void open() {
      System.out.println("open database for sales"); 
   }
   public void close() {
      System.out.println("close the database");
   }
   public void log() {
      System.out.println("log activities");
   }
   public void update() {
      //
   }
}
class Management extends Connection {
   public void open() {
      System.out.println("open database for management"); 
   }
   public void close() {
      System.out.println("close the database");
   }
   public void log() {
      System.out.println("log activities");
   }
   //...
}
class Controller {
   public static Accounting acct;
   public static Sales sales;
   public static Management manage;
   private static Connection current;
   
   Controller() {
       acct = new Accounting();
       sales = new Sales();
       manage = new Management();
   }
   public void makeAccountingConnection() {
       current = acct;
   }
   public void makeSalesConnection() {
       current = sales;
   }
   public void makeManagementConnection() {
       current = manage;
   }
   public void open() {
       current.open();
   }
   public void close() {
       current.close();
   }
   public void log() {
       current.log();
   }
}
class Test {
   String con;
   Controller controller;
   Test(String con) {
      controller = new Controller();
	  //the following trigger should be made by the user
      if(con.equalsIgnoreCase("management"))
	     controller.makeManagementConnection();
      if(con.equalsIgnoreCase("sales"))
	     controller.makeSalesConnection();
      if(con.equalsIgnoreCase("accounting"))
             controller.makeAccountingConnection();
      controller.open();
      controller.log();
      controller.close();
   }
}
class Server {
   public static Test test;
   public static void main(String[] args) {
      new Test(args[0]);   
   }
}

When we run the program with different connection, we will invoke the program in the following printout:

 C:\ Command Prompt
 
C:\> java Server management
open database for management
log activities
close the database

C:\> java Server accounting
open database for accounting
log activities
close the database

C:\> java Server sales
open database for sales
log activities
close the database

Return to top