Architecture & DesignLet the Application Flow Organize Your Objects

Let the Application Flow Organize Your Objects

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Introduction

While working as a software architect, I have felt an urge to do programming in a style that I call “Focus-Oriented Programming.” This is a style of programming that has advantages in the area of application maintenance, testing, and integration for reasons that will be obvious by the end of this article. I wanted to share this style of programming with the wider programming community so that more programmers can have more control on their code while they enjoy life, a practice that is not very common amongst hard-core developers too tied to their desks.

Concepts

First, I shall describe some conceptual terms I use:

  • Focus: Focus is any collection of objects and their behaviors. The only restriction is that you should be able to describe vividly what is going on in the focus in a short sentence and this description should preferably cover every object in the focus.
  • Flow: Flow is a sequence of focus objects. A flow should add up the behavior of focus objects and accumulate the behaviors. Flow too should have a concise description that summarises the building of behaviors through the accumulation of their focus objects.
  • Context: A Context is that which accumulates all the behaviors in one or more flows and prepares a final stage for an application feature.
  • Command Interface: A context can be started with a focus object that implements a command interface. A command interface is an interface with only one method with a signature:
  • public void  execute(Context c);

Implementation

I have a class for each of the fundamental concepts of Flow and Focus programmming. I have included the full source code of these classes along with the class codes for an application that maintains a list and has add and delete butttons to maintain list entries. The source code is provided in the zip file with this article. You can recompile the code or run with the supplied class files. FlowDemo is the main class to execute. I have tested the code using JDK 1.4. Each of Focus, Flow, and Context is a bean with one special Focus object, termed a CommandFocus object that implements the Command interface. A Flow bean and a Context bean are a listeners of a Focus bean. A Focus bean generates changes in the flowMap property in Flow and the contextMap property in Context. Each of these properties is a hash map containing the name versus objects passed from a different focus. Before going into too much implementation detail, I shall present the style of an application code using Focus and Flow orientation.

Application Style

The simple application is called FlowDemo and the class for FlowDemo appears below.

class FlowDemo  {

  Context myContext;

  public void FlowDemo(){
  }

  public static void main(String[] args) {
    //First, set up the CommandFocus object: that is the 
    //aim of this application.
    FlowDemoCommandFocus flowDemoCommand = 
               new FlowDemoCommandFocus();
    //create a context for that aim
    Context myContext = new Context(flowDemoCommand);
    //Identify two flows in this application
    Flow putInListFlow  = new Flow("set up a listbox 
               with 2 buttons to put and delete list entries ");
    Flow frameFlow  =
               new Flow("get the frame to come on the desktop");

    //First flow is expanded into 6 focus objects
    PanelFocus panelFocus = 
               new PanelFocus(putInListFlow,myContext);

    ListFocus listFocus =  
               new ListFocus(putInListFlow,myContext);

    AddButtonFocus addButtonFocus = 
               new AddButtonFocus(putInListFlow,myContext);

    DelButtonFocus delButtonFocus = new DelButtonFocus
               new DelButtonFocus
(putInListFlow,myContext);

    TextFocus textFocus  =  new TextFocus(putInListFlow,myContext);

    ListenerFocus listenerFocus = 
               new ListenerFocus(putInListFlow,myContext);

    //Second Flow has only one focus object
    FrameFocus frameFocus = new FrameFocus(executionFlow,myContext);

    //Context is ready to render/execute
    myContext.execute();
  }
}

As the accompanying comments describe, the command focus object is the focus to start with. The

command focus class appears below:

import java.io.Serializable;
class FlowDemoCommandFocus extends Focus 
           implements Serializable, Command {
  //standard super constructor
  public FlowDemoCommandFocus(Flow aflow,Context acontext){
     super( aflow,acontext);
  }
  public FlowDemoCommandFocus(){
     super();
  }

  public void execute(Context cc){
      JFrame frame = (JFrame)
                   (cc.getContextMap("flowdemo"));

      frame.pack();
      frame.setVisible(true);
      // this.synchronize();
  }
}

FlowDemoCommandFocus implements the Command interface that has got only one method: the execute(Context c) method. The initial command focus establishes our context that is created by using the command focus in its constructor. Next, the two flows are set up; they give us the scheme of actions to take to set up our application. The first flow establishes the panel with all its contents. The second flow sets up the frame and causes it to show itself on our screen. After setting up the flows, we go about expanding each flow in terms of its focus objects. The panelFocus object sets up the panels. The PanelFocus code appears below:

import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.io.Serializable;

class PanelFocus extends Focus  implements Serializable  {
  //standard super constructor

  public PanelFocus(Flow aflow,Context acontext){
    super( aflow,acontext);


    //setup panel and ui objects
    JPanel common = new JPanel();
    common.setLayout(new GridLayout(2,1));
    JScrollPane jp1 = new JScrollPane();
    common.add(jp1);

    JPanel lowerpane = new JPanel();
    lowerpane.setSize(1,2);


    common.add(lowerpane);
    //1 item put in Context
    this.putContextMap("commonpane",common);
    //the commonpane not needed in the current flow
    //2 items put in flow
    this.putFlowMap("panelforList",jp1);
    this.putFlowMap("lowerpane",lowerpane);
    //comit all changes:
    this.synchronizeFlow();
    this.synchronizeContext();
  }
}

The point to note is that PanelFocus object uses its super constructor, which takes the flow and context as parameters. Then, the whole activity of this focus is within the constructor itsef. It sets up one Jpanel object and one JscrollPane object to be accessed and modified in the current flow. To be accessible by a focus object in the current flow, the focus puts that object in the flowMap; however the commonpane is meant for the final frame which is set up in the second flow—the frameflow—to be accessed by a different flow the focus puts the object in contextMap property. The putFlowMap, getFlowMap, putContextMap, and getContextMap methods of the focus class provides the mechanism to put and get named objects from the Context and the Flow objects. Finally, the synchronizeFlow and synchronizeContext methods commit all the changes from the current focus. ListFocus is the next focus in the flow. The code for list focus appears below:

import java.util.*;
import javax.swing.*;
import java.io.Serializable;
class ListFocus extends Focus  implements Serializable  {
  //standard super constructor

  public ListFocus(Flow aflow,Context acontext){
    super( aflow,acontext);

    JScrollPane jp1 = 
        (JScrollPane)(this.getFlowMap("panelforList"));
    JList l1 = new JList(new DefaultListModel());
    jp1.setViewportView(l1);
    this.putFlowMap("list",l1);
    this.synchronizeFlow();
  }
}

The ListFocus acquires the JScrollPane object by its name and attaches a viewport to it while also passing a new list object used in the viewport as an object with the name “list.” Similar actions happen with the focus object that follows. When you go to the next flow, the frameFocus focus object acquires the commonpane from the contextMap. Once you have set up all the flows, the context is ready to be executed.

Scalability

No doubt for a simple application like the one for FlowDemo, the elaborate flow and focus mechanism is an overkill. On the performance side, as long as the focus and flow are in the same JVM, there is not much performance penalty. However, the big plus you can see very clearly is how a separation of concerns has been maintained here. For example, when setting up a listener you don’t care what the position of the button or list was or when buttons were set up; you don’t need to care about panel layout, and so forth. Thus, this example establishes Flows and Focus concepts.

Flow Benefits

If you look upon an application as a collection of flows, then the integration and testing of these applications is much more streamlined. First, for testing purposes, each focus object can have its own assertion clause and can be individually tested. Application integration will immdiately equate to mapping application flows to business flows resulting from the integration and vice versa. This will represent a more direct approach to application integration.

The fact that flows themselves are represented as individual objects has a big implication at the architecture level. For example, a pattern such as Business Delegation in J2EE now can be represented as a flow in which some focus represents the lookup service with some specific implementation details; for example, the directory service used and another represents business service with specific business service, such as “doing shop floor tracking for display items in a retail shop.” The individual focus refers to objects by their name without the object necessarily being created. In a future article, I shall describe the role of flows in the wider context.

In the meantime, feel free to reuse the Focus and Flow classes and let me know what interesting flows and their context you arrive at. I have not seen too many references to the issue of flow representation within an application except the fact that applications do have flows. One recent article points to the benefit of treating the flows as representable entities[1].

To download the demo click here.

References

[1]”Decoupling Application Logic, Persistence, and Flow: The Model Technique” by Michael Nash in www.developer.com/design/article.php/3306961.

About the Author

Pronob has been a software developer working at Visual Analytics, Sydney. He holds a MS in Applied Mathematics from Calcutta University and a MSE in Computer Science from IISC Bangalore,India. During the 22 years of software development assignments he has worked mainly on the mainframe and midrange platform software and application architecture areas. Since 2001 he has adopted java as his pet language after having been certified by Sun.

# # #

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories