Go to primary content
Oracle® Retail POS Suite Implementation Guide, Volume 2 – Extension Solutions
Release 14.1
E54476-02
  Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

4 Point-of-Service Development Standards

The following standards specific to the Point-of-Service architecture have been adopted by Oracle Retail product and service development teams. These standards are intended to reduce bugs and increase the quality of the code.


Note:

See the Oracle Retail POS Suite Security Guide for more information about specific security features and implementation guidelines for the POS Suite products.

Screen Design and User Interface Guidelines

Avoid creating new screen beans and screen models for every new screen. Look for ways to reuse existing or generic beans, such as the Data Input Bean, to avoid complicating the code base.

Tour Framework

This section includes general guidelines as well as subsections on specific tour components.

For more information, see Chapter 12.

Tour Architectural Guidelines

Consult these guidelines when making architecture decisions in tour framework designs.

  • Services—When designing services, consider their size and reusability. Services that are overlarge create additional work when a portion must be extended.

  • Utility Manager—Put methods used by multiple services in this manager so they can be easily extended.

  • If the reusable behavior contains flow-dependent behavior, then it is best implemented as a Site and the Site action can be reused within a Service or across Services.

  • Large bodies of reusable behavior can be implemented as Managers and Technicians. This pattern is especially useful if the user might offload the processing to a separate CPU.

General Tour Guidelines

  • Code that uses bus resources must reside in a Site action, Lane action, Signal or Shuttle.

  • Never mail a letter from a Road. This causes unpredictable results.

  • Never define local data in a Site, Aisle, Road or Signal. Local data is not guaranteed when processing across multiple tiers. Sites and Lanes must be stateless. This is the purpose of Cargo.

  • Traffic Signals should not modify Cargo. Signals should only be used to evaluate a condition as true or false. Anything else is a side effect, reducing the maintainability of the system.

  • Never implement just one Signal. Always implement Signals when there is more than one Road that responds to the same letter, or when there is an Aisle and a Road that respond to the same letter. See Signals.

  • Send letters at the end of methods. If the choice of which letter to send depends on conditions which occur during the method, store the method name and mail it at the end of the method.

  • Do not mail letters from depart() and undo() in Sites, backup() and traverse() in Roads, roadClear() in Signals, and load() and unload() in Shuttles. Letters can be mailed from traverse() in Aisles.

  • Define Shuttles in the calling Service package. If they are reusable Shuttles, define them in a common package.

Table 4-1 provides naming conventions for Tour components.

Table 4-1 Tour Naming Conventions

Element Description Example

Service

description of the related functionality

Login

Site element

VerbNoun—indicating the action taking place at the Site

EnterID

Site class

The same as the Site name, with Site as a suffix

EnterIDSite.java

Road element

NounVerb—indicating the event that caused the Road to be taken

IDEntered

Road class

The same as the Road name, with Road as a suffix

IDEnteredRoad.java

Aisle element

NounVerb- indicating the event that caused the Aisle to be taken

PasswordEntered

Aisle class

The same as the Aisle name, with Aisle as a suffix

PasswordEnteredAisle.java

Cargo

ServiceNameCargo

LoginCargo.java

Letter

One word action name indicating the event; see list defined in commonLetterIfc.java

  • Success

  • Failure

  • Continue

  • Next

  • Cancel

  • OK

  • Retry

  • Invalid

  • Add

  • Yes

  • No

  • Undo

  • Done

Transfer Station element

NestedServiceNameStation

FindCustomerStation

Shuttle class

NestedServiceNameLaunchShuttle

NestedServiceNameReturnShuttle

FindCustomerLaunchShuttle.java

FindCustomerReturnShuttle.java

Traffic Signal class

IsCondition.java-indicating the condition being tested

IsAuthRequiredSignal.java


Foundation

  • The best reuse in the Foundation engine takes place at the Service level. Sites require extra thought because they can affect flow. Lane actions can be reused without flow implications. Signals and Shuttles are very well suited to reuse especially when interfaces are developed for accessing Cargo.

  • If validation and database lookup are coded in Aisles, they may be good candidates for reuse in several Sites as well as in multiple Services.

  • All component pieces need to be designed with care for reuse: they must be context insensitive or must do a lot of checking to make sure that the managers they access exist for the bus that is active, the Cargo contains the data they need, etc.

  • Trying to maximize reuse can result in confusing code with too many discrete parts. If the reusable unit consists of one or two lines of code, consider whether there is sufficient payoff in reusing the unit of code. If the code contains a complex calculation that is subject to change over time, then isolating this logic in one place may be well worth the effort.

Tours and Services

  • There is often a one-to-one mapping between a Use Case and a Service. The Service should provide the best opportunity for reuse. If you design for reuse, it should be focused at the Service level. This is where you get your best return on investment.

  • Maintenance is a matter of choosing a style and implementing it consistently within a Service and sometimes within an entire application. When you are comfortable with how TourCam works, maintaining TourCam Services is easy.

  • Aisles help reduce the total number of Sites in a Service, but they may be harder to see because they are contained within a Site.

  • When making choices, give making an application as consistent and easy to maintain as possible the top priority.

  • Consider the performance costs of using TourCam or creating additional Sites when designing a Service.

  • A Service can often be simplified by reducing the number of individual Sites. You can do this by using Aisles to replace Sites; Sites with one exit Road can be good candidates, and Aisles are good candidates for reuse. However, Aisles are less visible than Roads.

Sites

  • Reusing a Site has flow implications. Site classes can be reused whenever the exit conditions are identical. Reusable Sites should be packaged in a common package as opposed to one of the packages that use them. A reusable Site must refer to a reusable Cargo or a common Cargo interface.

  • Treat the sending of a letter like a return code: put it at the end of your arrive() or traverse() method. Sending letters in the middle of the arrive() method may cause duplicate letters (with unpredictable results), or no letters (with no results).

  • Do not try to store state information in instance variables. Pass in state information through arguments.

  • Do not put a lot of functionality in arrive(), traverse() methods. Decompose them into logical methods that each have one job. For methods not called from outside the package, protect the methods.

Managers and Technicians

  • There is a high degree of reuse of Managers and Technicians across the applications. For example, the DataTransactions and DataActions are reusable. By design, it is the DataOperations that change with different database implementations. The UIManager and UITechnician expect a lot of reuse of beans, adapters, and specification objects. In fact, the UISubsystem looks in the UI Script for most of the configuration information that effects changes in screen layout, bean interactions and even bean composition.

  • Utility methods can be useful for capturing behavior that is used by many Services, but does not lend itself to Site or Aisle behavior. Put Utility methods in a UtilityManager so they can be easily extended. The Point-of-Service application contains an example of this called the POSUtilityManager. Service developers can access these methods through the POSUtilityManagerIfc. The UtilityManager and UtilityManagerIfc classes can be extended and the new class is specified through the Conduit Script. For general-purpose behavior that can be called from a Site, Lane, or even from a Signal, use utility methods to capture the common reusable behavior rather than extending a common Site.

  • Large bodies of reusable behavior can be implemented as Managers and Technicians. This pattern is especially useful if the user might off-load the processing to a separate CPU.

Roads

It is sometimes useful to define multiple Roads from an origin Site to the same destination if they capture different Road traversal conditions.

Do not trap and change the name of a letter just to reduce the number of Roads in a Service. This is a poor use of system resources and also hides useful information from the reader of the Tour Script. Do not rename letters except as noted in Renaming Letters.

For example, the Return Transaction Service has two Roads with the same origin (LookupItem) and the same destination (EnterReturnItemInformation), but the letters that invoke these two Roads are different.

The use of Road actions is dependent on a number of factors: use of TourCam, developer conventions for an application, number of classes generated, and maintainability.

Use Road actions for outcome-specific behavior. If you need to store some data in Cargo on the sending of a specific letter, do the Cargo storage in the traverse() method of the Road that is associated with that letter. If the data must be stored in Cargo before leaving a Site, put the logic in the Site's depart() method. Code in a Site or Aisle's depart() method should not check to see what letter was sent before taking an action; use a Road in that case.

Aisles

Aisles are used to implement behavior that occurs within a Site. When there is interaction with an external source (e.g. user, database) use a Site. When you are doing business validation which may keep you in the same screen, use an Aisle.

While it makes sense to create Roads without corresponding Road actions, Aisles are useless without an Aisle action. The important thing about an Aisle is that it is not part of a transition from one Site to another, so the only code that gets executed in an Aisle is the traverse() method. The arrive() and depart() methods are never executed on a Site when an Aisle is processed. The Aisle can initiate an action that causes a transition to another Site, but it cannot transition itself.

Aisle actions can be used to validate data, compute values, provide looping behavior, and do database lookups. Aisle actions are useful for capturing repeatable behavior that can occur while the bus is still in a Site.

For example, suppose you define a Site that gathers data from the user. The data validation is implemented as an Aisle. Because it is an Aisle, the user can repeat the process of entering data, validating, and re-entering until the data is correct, with little system overhead. The Aisle behavior can be triggered over and over without calling the arrive() method on the Site (a Road back to the Site calls the arrive() method).

Aisles are also useful for looping through a list of items when each item may require error handling. This is done by placing the loop index in the Cargo.

Signals

You cannot use a signal alone; they must be used in groups of two or more. If there is more than one Lane that responds to the same letter, each Lane must implement a Signal. The logic in the Signals must be mutually exclusive; there should be only one valid Road that can be traversed at any time; otherwise, unexpected (and difficult to debug) behavior could occur.

When there are more than two Signals, each of the Signals should evaluate in such a way that only one Signal is green at any given time. But the presence of more than two Signals should raise a red flag. Track down the source of the following issues; determine if the UI or other letter generator needs to be sending more unique letters.

  • Why are there so many Signals?

  • What are they checking?

  • Is the same letter being sent for many different conditions?

Use a Signal only to decide which road to take when you could go to two different places (such as Sites) with the same Letter, based on Cargo information. It should not be used to update cargo. The road you take after making a decision at the Signal should do the updating.

Choosing Among Sites, Aisles, and Signals

There are many times when an Aisle can do the same work as a Site. Sometimes a Signal can contain behavior that could be implemented in an Aisle. Sometimes a separate Service does the work that was once a Site if the Site needs to be reused or becomes too complicated. Consult the guidelines for your application development team in order to be consistent with the rest of your team.

If you have the following customer requirement:

  • Display a UI screen that gathers search criteria to be used in a database lookup (for example, customer lookup). After the user enters the data, validate the data. Once the data has been validated, do the database lookup.

you have the following design choices:

  • Implement as separate Sites and take advantage of TourCam to back up when the data is invalid or database lookup results are not correct.

  • Implement as one Site with Aisles that do the validation and lookup.

The database lookup may result in a success or failure letter whether it is coded as a Site or an Aisle. When using an Aisle for database lookup, the failure letter triggers another Aisle that could display an error message but allow the user to re-enter the data and retry the lookup. This can occur without exiting the original Site. When using a Site, the failure condition can trigger a flow change to back up through the lookup Site back to the data entry Site.

If the validation and database lookup are coded in Aisles, they may be good candidates for reuse in several Sites as well as in multiple Services. Reusing the Site is also possible, especially if the TourCam's ability to back up to the last indexed Site is used. But there may be more considerations involving flow when trying to reuse a Site.

Renaming Letters

Use the following guidelines when deciding whether to rename letters:

  • Do rename Letters when the application developer does not have power over the Letter that is mailed and there is more than one event associated with a single Letter.

    For example: a single Letter is sent from a button on the UI (such as dialog box OK), but the content of the retrieved data associated with the UI signals a different event notification (such as error message notification).

  • Do rename Letters when a common exit Letter from a nested Service is needed.

  • Do not rename Letters to reduce the number of Roads in a Service.

Shuttles

If you are creating a sub-tour (that is, a tour called from other tours using a Station) from scratch, use only the following final letters:

  • Success

  • Failure

  • Cancel

  • Undo

If you need to provide a reason for a Failure or need to return data to the calling service on a Success, use the Return Shuttle to update the calling service's cargo. Do not use letters to reflect sub-tour results.

Shuttle Type Launch Shuttle Return Shuttle
Description Used to send parameter data to a sub-service Used to return data to the parent service.
Methods load()—can only see the parent Service's Cargo

unload()—can only see the sub-service's Cargo

load()—can only see the sub-service's Cargo

unload()—can only see the parent service's Cargo


Within the Tour Framework, Shuttles are used to transfer data in and out of Services. Shuttles are good candidates for reuse given a common Cargo interface.

Cargo

All Cargo classes should implement the CargoIfc interface.

Log Entry Format

This section describes the format and layout of log entries for the Point-of-Service application.

Log Entry Description

Log entries adhere to the following format:

LLLLL yyyyy-mm-dd hh:mm:ss,ttt bbbbbbb (<classname>):
      [<classname>.<methodname>(<filename>:<linenumber>)]
      <Log entry content>

Fixed Length Header

The entry begins with a fixed length record header (38 bytes) that adheres to the following layout:

LLLLL yyyyy-mm-dd hh:mm:ss,ttt bbbbbbb 
12345678901234567890123456789012345678
 

LLLLL is the log message level and consists of one of the substrings in the following table.

Table 4-2 provides log message levels and their descriptions.

Table 4-2 Log Message Level

Log Message Level Description

ERROR

Highest severity entry; critical

WARN

Application warning; serious

INFO

For information only

DEBUG

For developer use (not displayed by default application configuration


yyyy-mm-dd is the date.

hh:mm:ss,ttt bbbbbbb is the time stamp of the entry, comprised of the sub-fields described in the following table.

Table 4-3 provides time stamp fields and their descriptions.

Table 4-3 Time Stamp Fields

Field Description

hh

Time of entry in hours, in 24-hour format

mm

Minutes past the full hour

ss

Seconds past the last full minute

ttt

Milliseconds past the last full second

bbbbbbb

Milliseconds since the application was started. Left justified and blank filled on the right, out to 7 places


Additional Logging Information

The fixed length record header is followed by a blank space followed by the parenthesized, fully qualified class name of the logging entity followed by a colon followed by a carriage return/line feed pair.

(<classname>):<cr><lf>

The next line in a log entry begins with 6 blank spaces and a square-bracketed sequence containing the following information:

<classname>.<methodname>(<filename>:<linenumber>)

Parentheses are included in the sequence. This sequence reflects the fully qualified name of the method invoking the logging action and the source line number in the file where the logging call was made.

The next lines in a log entry are the log entry content. The content is comprised of freeform text supplied by the calling routine. The content reflected in the freeform text may be multiple lines in length.

The next log entry is delineated with another 38 byte fixed length header beginning in column one of the text log file.

Example Log Entry

INFO  2004-09-02 11:12:41,253 23697  (main:oracle.retail.stores.foundation.manager.gui.DefaultBeanConfigurator):
      [oracle.retail.stores.foundation.manager.gui.DefaultBeanConfigurator.applyProperties(DefaultBeanConfigurator.java:198)] 
      Applying property cachingScheme to Class: DialogBean (Revision 1.9) @12076742