55
Bridging Java Presentation and Business Logic with an Application Model Nathan Carpenter RABA Technologies

Bridging Java Presentation and Business Logic with an Application Model Nathan Carpenter RABA Technologies

Embed Size (px)

Citation preview

Bridging Java Presentation and Business Logic with an

Application Model

Nathan Carpenter

RABA Technologies

Purpose

Show how the Application Model design pattern provides a session-based state management solution that bridges the gap between the presentation and business tiers in a Web application

Agenda

Background

Problems Addressed

The Application Model Pattern

Implementing an Application Model

Conclusion

Background

Three Tier systems are very common today– Presentation Tier displays data to the

user (JSP, Swing GUI)– Business Tier provides rules and logic

for manipulating the data (Servlets, Session Beans)

– Data Tier handles persistence of data (Entity Beans, Data Access Objects, JDBC)

Background

Many patterns exist for Business and Data Tiers and communications between them– Session Façade, Value Object, Data

Transfer Object, others

Limited patterns exist for Presentation Tier or for its communication with Business Tier– Business Delegate

Agenda

Background

Problems Addressed

The Application Model Pattern

Implementing an Application Model

Conclusion

Problem

Three major problems between Presentation and Business Tiers

– Properly designed Business Tier is client-agnostic

– Stateless nature of Web-based interfaces makes keeping client state difficult

– Presentation components must be decoupled from business communication logic

Client Agnosticism

Business Tier interfaces should be developed to be useful to any number of clients– Client requirements often creep into

Business Tier code– Decreases broad utility of Business

Tier– Changes to the business logic may

affect clients negatively

Stateless Clients

Web interfaces are inherently statelessClients often need to maintain some kind of state

– State should not be managed by the business tier, since it is a client-specific need

– State management in Web interfaces can be done with the Session

– Namespace conflicts and state validation problems can become an issue in a large system

Decoupling Presentation Components

JSPs, Custom Tags, and Struts Actions should contain no business logic or ties to the business interface– Limits impact of changes in

presentation logic and business logic– Both change often during system

development

Need an adapter between presentation API and business API

The Application Model Pattern

Provides a session-based state management solution that bridges the gap between the Presentation and Business tiers

Works hand-in-hand with Business Delegate pattern to provide a client-specific interface to the Business Tier

Used by Web-based display components such as JSPs, custom tags, and Struts actions

Agenda

Background

Problems Addressed

The Application Model Pattern

Implementing an Application Model

Conclusion

The Application Model Pattern

Forces

Solution

Participants and Responsibilities

Strategy

Consequences

Related Patterns

Forces

Business tiers are client-agnostic and provide data in least-common-denominator fashion

Web-based interfaces are inherently stateless and need a standard way to manage state information

It is desirable for clients to cache data from the server to reduce round trips

Display components such as JSPs, custom tags, and Struts actions should not perform data translation and composition

Solution

Use an Application Model to provide a client-specific interface to one or more business services, with caching and manipulation of the server-provided data encapsulated within a client-oriented model

Benefits of Solution

Provides the interface that display-oriented components use to access the business tiers

Yields a highly client-oriented interface that acts as a façade to multiple Business Delegates and Service Locators

Acts as the Model while the display components act as the View and the web framework acts as the Controller

Structure of Application Model

1..*

Participants And Responsibilities

Client submits a request to the

Controller (usually a Servlet or JSP)

Participants And Responsibilities

Controller retrieves an instance of the

Application Model from the Session

Participants And Responsibilities

Controller executes method to access state

maintained by the Application Model

Participants And Responsibilities

Application Model returns stored state or uses Business

Delegate to get remote information

Participants And Responsibilities

Application Model returns control to the Controller

Participants And Responsibilities

Strategy

Implement the Application Model as a Session Singleton– One instance of the Application Model

per user– Instance stored in the user’s Session– Expires when session is invalidated

Details in the Implementation section

Consequences

Provides a client-oriented API for display components– Takes the client-agnostic APIs

generally provided by Business Delegates or Session Facades and creates a client-specific API

– Within the Application Model, data is transformed based on client-specific requirements and cached if needed

Consequences

Allows the Web application to maintain state using a consistent strategy– Reduces risk of namespace conflicts

between developers in complex systems

– Allows for related data to be logically grouped in the session and in code, which simplifies debugging and maintenance

Consequences

Gives the Web application a consistent means for checking for loss of state– State validity checking is encapsulated

into the instance retrieval method– Application Model can ensure that it is

in the proper state before responding to any call

Related Patterns

Business Delegate– Encapsulates the remote

communications methods– Maps network exceptions into

business exceptions

Service Locator– Looks up remote objects if a Business

Delegate does not exist for the remote interface

Agenda

Background

Problems Addressed

The Application Model Pattern

Implementing an Application Model

Conclusion

Basic Requirements

Must be Serializable to store in the Session

Needs a unique handle to prevent namespace conflicts in the Session

Has to be able to tell if the Session was invalidated between calls to the instance

Needs a method to retrieve an instance from the Session

public class MyAppModel implements Serializable

{

private static final String SESSION_NAME =

MyAppModel.class.getName();

private boolean transient isModelValid = false;

private DemoBusinessDelegate delegate = null;

// Other member variables go here

// Mark any nonserializable ones as transient!

Core Implementation

protected MyAppModel(HttpSession session)

{

// Initialize the business delegate(s)

this.delegate = new DemoBusinessDelegate();

   // Initialize other models or members

// Set the model state to valid

this.isModelValid = true;

}

Core Implementation (cont.)

public synchronized static MyAppModel getSessionInstance(HttpSession session)

{  Object o = session.getAttribute(SESSION_NAME);

  if (o == null || !(o instanceof MyAppModel) ||      !(((MyAppModel)o).isModelValid)) { o = new MyAppModel(session);    session.setAttribute(SESSION_NAME, o);  }

  return ((MyAppModel)o);}

Core Implementation (cont.)

Implementation Notes

Constructor must be protected to ensure singleton status

All non-serializable members must be marked transient

All public methods that manipulate member variables must be synchronized in case a user makes many requests rapidly

Demonstration Model

Build an application model to interface to a simple personnel database

• Employee has name and address• Server API has following methods:

public Employee getEmployee(employeeId)

public Employee[] getEmployees()

public void addEmployee(Employee employee)

Build Client API

Add code to support these client functions• Retrieve a single employee and display

their information• Retrieve employee names and

addresses from the server and cache them for display

• Create a wizard allowing entry of an employee record

Retrieve Employee

Make a call to the business delegate passing the employee’s ID

Let’s also figure that the client will want to operate multiple times on the same employee, so we should cache the result

private Employee cachedEmployee = null;

public synchronized Employee getEmployee(String id) {

  if (this.cachedEmployee == null ||

      !(this.cachedEmployee.getEmployeeId().equals(id)))

{

    this.cachedEmployee = delegate.getEmployee(id);

  }

  return this.cachedEmployee;

}

Model Implementation

<%

MyAppModel myAppModel =

MyAppModel.getSessionInstance(session); 

String id = request.getParameter(“employeeId”);

Employee employee = myAppModel.getEmployee(id);

%>

<UL>

  <LI>Name: <%= employee.getLastName() + “, ”

+ employee.getFirstName()%></LI>

<UL>

JSP Implementation

Retrieve Employee List

Make a call to the business delegate and get the array back

Let’s also figure that the client will want to operate multiple times on the same list, so we should cache the result

private Employee[] cachedEmployees = null;

public synchronized Employee[] getEmployees() {

  if (this.cachedEmployees == null)

{

    this.cachedEmployees = delegate.getEmployees();

  }

  return this.cachedEmployees;

}

Model Implementation

<%

MyAppModel myAppModel =

MyAppModel.getSessionInstance(session); 

Employee[] employeeList = myAppModel.getEmployeeList();

%>

<!-- Now iterate over the records and display them -->

<% for (int i = 0; i < employeeList.length; i ++) { %>

<!-- Display one record -->

<% } %>

JSP Implementation

Adding Employee

Previous examples focused on caching – this example will focus on state management

Data Entry is often a multistage, branching process

Real power of Application Model is here

Desired Outcome

We’ll simulate a “wizard” for entering employee information

• First, enter first and last name and continue

• Next enter address and save record

Real application would be more complex

Strategy

We’ll create a “working” Employee object managed by the Application Model

When all information is complete, this will be passed to the Business Delegate for saving

private Employee workingEmployee = null;

public void setWorkingEmployee(Employee e) { … }

public Employee getWorkingEmployee() { … }

public synchronized void addEmployee(Employee employee) {

delegate.addEmployee(employee);

this.employees = null;

this.currentEmployee = employee;

}

Model Implementation

The first step in the Wizard would fire the following Controller action

/** setup action **/

Employee employee = new Employee();

employee.setEmployeeId(String.valueOf(new java.util.Date().getTime()));

employee.setFirstName(form.getFirstName());

employee.setLastName(form.getLastName());

myAppModel.setWorkingEmployee(employee);

/** rest of action **/

Controller Implementation

The second step in the Wizard would fire the following Controller action

/** setup action **/

Employee employee = myAppModel.getWorkingEmployee();

employee.setStreet(form.getStreet());

employee.setCity(form.getCity());

employee.setState(form.getState());

employee.setZip(form.getZip());

myAppModel.setWorkingEmployee(null); // We’re done

myAppModel.addEmployee(employee);

/** rest of action **/

Controller Implementation

Demo

When To Use

Use when you have complicated branching of requests while building up enough state information for a submission– Redundant for simple form state

management problems since Web framework such as Struts and JSF provide standard constructs for this

When To Use

Use when Presentation Tier use cases do not map well to Business Tier use cases– Adds needless level of indirection if

you have a one-to-one method and exception mapping in your Application Model with no additional logic

When To Use

Use for caching of server information when it doesn’t involve very complicated rules or huge data sets– Complicated caching logic is best

handled by an off-the-shelf caching solution

– Large data sets will overwhelm the session and are better handled by a focused caching solution

Agenda

Background

Problems Addressed

The Application Model Pattern

Implementing an Application Model

Conclusion

Conclusion

The use of an Application Model– Allows Web client developers to create a

client-oriented API– Encapsulates caching and data

transformation specific to the client’s needs– Maintains state in a more predictable way

than simply storing data in the session– Takes advantage of the Business Delegate

and Service Locator patterns as best practices

Questions

Contact Me– [email protected]

Get The Code– http://www.jugaccino.org

Thanks For Attending!