ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Brewing Java at the Point of Sale

by Quentin Olson
09/20/2001

Many of us don't realize it (or think about it), but the point of sale (POS) is a remotely-managed application and it has been for years. Next time you visit a restaurant chain or an enterprise grocer, think about the technology behind the cash register and what must be involved in updating prices and software. In practice, the state of these enterprise systems run the gamut from off-the-shelf standalone registers backed by an army of key entry personnel to highly customized (proprietary) systems using various high-speed technologies to form vast private wide area networks (WANs). Few standards exist, and the implementation of those standards is ad-hoc at a best. One common theme is that all of the software is proprietary and expensive, which puts enterprise functionality out of the reach of smaller operations and single shop owners.

This article examines an open source POS application written in Java and the use of certain Java functionality to reduce complexity, in order to implement a broadly-applicable POS transaction engine. To many Java-literate readers, the Java features described may be old news, but it may be of interest to see how some of the more arcane Java features are used in this non-Web application. Also, since this article describes an open source project for enterprise retailers, it goes into considerable architectural detail regarding POS functionality as it applies to enterprise retail environments.

Why Java?

Java has emerged in recent years as a common platform used by retailers to reduce software complexity and management requirements. Why? Java supplies many of the tools we require to build applications in a smaller footprint -- examine the Java SDK at 50 megabytes, compared to the Windows SDK footprint. Java includes unique functionality not widely available in linked architectures -- dynamic class loading and serialization. As a footnote, it is possible to perform dynamic class loading in C++ under Linux, but it is not widely used and is not regarded as a fundamental language feature as it is in Java.

The resounding argument against the use of Java is its large memory footprint and slow performance. But in practice, this argument is losing its punch; it's no longer possible to buy a new computer that is too slow to use Java and smaller devices are beginning to be well-supported by the Java ME (Micro Edition) platform. To be honest, I can't say that Java is overwhelmingly poised to take the retail world by storm. Many retailers have a large installed base of older hardware that they are not ready to throw away, and if you were to look today, you would not find universal Java support for retail peripherals by the major hardware vendors. The industry is changing, though, and quickly. Most hardware vendors have recognized the advantages in the Java platform.

POS OO Architecture

POS architecture provides a classic exercise in object orientation. First, you have something called an electronic journal, that is basically the memory version of your receipt. The journal contains lines for the various sub-components of a sale, such as an item, a tax record, or a tender (cash, check) record. They all have an amount, a quantity, etc. Are you starting to visualize the abstract interface? You also have devices: receipt printers, customer displays, scanners and scales. Look at these statements, if you still need convincing:

[cw]
receipt().print (ejItem);
receipt().print (ejTax);
[ecw]

and,

[cw]
operatorPrompt().print (ejItem);
operatorPrompt().print (ejTax);
[ecw]

It's quite easy to design an object-oriented POS application, but you could do this in any OO language. Java, however, has some language features that, in a enterprise retail environment, are very attractive. These can generally be categorized in the context of remote support and generalized application-building. But first, let's look at some additional design criteria intended to justify the use of Java's other features.

Event Engine

If you want a POS application that can be applied across retail disciplines (grocery, hard goods, restaurants) and across international borders, what you want to create is an event engine. That is an application that is capable of processing generic events and realizing the results of these events in the context of arbitrary hardware devices. The event concept is pretty easy; many modern development tools revolve around the event model, and Java is no different. What is important about a generalized POS application is that the events need to be user-programmable, and, preferably, not statically linked. You also need a way of stacking them up to create dialogs.

Dynamic Class Loading

Well, we still haven't examined anything that could not be implemented in any OO language, so let's do that now. POS applications makes use of dynamic class loading as part of their central event engine logic. Take a look at the following SQL POS key definition:

[cw]
create table pos_key (  
       key_id integer, 
       key_type integer, 
       key_val integer,
       key_code integer,
       x_loc integer,
       y_loc integer,
       key_class varchar(100));
[ecw]

The Java class that is invoked when the key is pressed (key_class) was dynamically loaded into a PosEvent object when the application initialized (actually when the operator logged on). PosEvent is an abstract class that encapsulates discrete POS business logic. When a key is pressed, the following code is invoked:

posEvent().engage();

The engage() method contains the business logic for the event; posEvent() is the key that was pressed. Events in a POS application are things like pressing the total key or scanning an item. But there are also dialogs, such as a check validation, credit card validation, or simply an operator logon. These are implemented by stacking events and maintaining state through those events.

A Closer Look at Dynamic Class Loading

In its simplest form, dynamic class loading looks something like this:

[cw]
Class class = findSystemClass(className);
PosEvent posEvent = (PosEvent) class.newInstance();
[ecw]

className is the string representation of your class, com.globalretailtech.pos.events.TotalKey, that extends PosEvent. The class loader in this application extends java.lang.ClassLoader (findSystemClass()), and uses the newInstance() method from Class to instantiate an object. You also need to wrap it in exception handlers to catch class not found and class cast exceptions.

Beyond Events, Promotions

Retail computing environments change daily. In the Customer Relationship Management (CRM) world, we call them the three P's: products, pricing, and promotions. It's the same thing in the retail world. New products are added and removed, prices change daily, and new and better (subtler?) promotions are always being invented by crafty sales types. It's this third category that makes dynamic loading very useful in retail environments.

A promotion may be a simple discount (i.e., % off an item), or it may be a more complex operation. Example: if a customer buys three or more bakery products, this may prompt the cashier to upsell the margarine that we double ordered last month. They both work the same; a promotion is applied to one or more items within the sale.

Comment on this articleDo you see Java making a large impact in POS system development?
Post your comments

So what does dynamic loading do for promotions? It would be difficult to capture both of the above logical operations in a single promotion module and then use some parameter to activate them. Well it wouldn't be difficult, but it would be very ugly. This is typically the case in many POS applications in production today. A promotion module captures many of the various common promotions that enterprises like to use. Then the software vendor adds whatever custom promotion types the retailer requests, and they are all managed through heavy parameterization. Some vendors have scripting capabilities but this adds the overhead of the interpreter. In the end, you have a promotion module with a lot of stuff you don't use and too many parameters to manage.

On the other hand, if you load a promotion dynamically, linked to an item or product group, it is very easy to manage and you can pick and choose what promotions you like to use. Furthermore, if a promotion is linked to an item or product group (via the database), you have a consistent mechanism for managing this functionality in the field. A promotion doesn't need to be a promotion, either; it could also be used to collect demographic information related to an item or group of items.

Pages: 1, 2

Next Pagearrow