Business Logic

Goal

Concepts

Lesson

You've already learned that a well-written program will separate its various concerns into different sections of the code. A program's most important concern is its central functionality, its reason for being. Somewhere between accepting input and producing output, a computer program usually does something. Massaging user input so that it can be better processed is ancillary to this task. Logging is a separate issue. Even producing the output is somewhat of an afterthought; because the program may have the ability to output data in a variety of formats or suppress output altogether.

The part of a computer program that handles what the program actually does between input and output is referred to as its business logic. You saw the general layers of a multi-tiered program when you focused on the presentation layer. Business logic sits in a layer under the presentation layer and concerns itself with the core program functionality, leaving data storage to the data layer and communication with the user to the presentation layer. The business logic layer is all about doing work.

A three-tier application.
A three-tier application. Modified from diagram by Bartledan (Wikimedia Commons).

Managers

You've already seen and implemented the repository design pattern. The repository sits on edge of the data layer and provides an abstraction for serializing and deserializing individual resources. We need a similar interface to sit in the business logic layer to encapsulate the main logic of our application and talk to other components such as a repository.

One such interface might implement the mediator design pattern. The purpose of this design pattern is to help manage the interaction among various objects and types of objects. For this reason many times an interface for the mediator design pattern will be referred to as a manager. For example consider a farm with many animals. There might be a BarnyardManager to keep track of the farm structures, along with which animals live in which parts of the farm.

The mediator design pattern as a manager of a barnyard.
public interface BarnyardManager {

  Set<Barn> getBarns() throws IOException;

  Barn addBarn(String name) throws IOException;

  Set<Pen> getPens() throws IOException;

  Set<Animal> getAnimals(Barn barn) throws IOException;

  void addAnimals(Barn barn, Set<Animal> animals) throws IOException;

  void removeAnimals(Barn barn, Set<Animal> animals) throws IOException;

  Set<Animal> getAnimals(Pen pen) throws IOException;

  void addAnimals(Pen pen, Set<Animal> animals) throws IOException;

  void removeAnimals(Pen pen, Set<Animal> animals) throws IOException;

}

Services

Another interface you will see in the business layer is one that will provide a service to the rest of the application. The implementation of the service interface(s) may in turn talk to managers in order to perform their services.

We can make a service for taking care of tasks on a farm.

A service interface for providing farm-related functionality.
public interface FarmService {

  void feedAnimals() throws IOException;

}

The implementation of this service will likely use the BarnyardManager.

Delegating to the BarnyardManager in the FarmService implementation.
public class FarmServiceImpl implements FarmService {

  private final BarnyardManager barnyardManager;

  public FarmServiceImpl(@Nonnull final BarnyardManager barnyardManager) {
    this.barnyardManager = checkNotNull(barnyardManager);
  }

  @Override
  public void feedAnimals() throws IOException {
    //external iteration on barns used for clarity; could have used flatMap(…)
    for(final Barn barn : barnyardManager.getBarns()) {
      barnyardManager.getAnimals(barn).forEach(this::feedAnimal);
    }
    for(final Pen pen : barnyardManager.getPens()) {
      barnyardManager.getAnimals(pen).forEach(this::feedAnimal);
    }
  }

  protected void feedAnimal(final Animal animal) {
    throw new UnsupportedOperationException();	//TODO feed animal
  }

}

Review

Summary

Gotchas

In the Real World

Think About It

Self Evaluation

Task

The marketing department contacts your team to request additional functionality in the Booker application. Until now Booker application has been tracking books in the sense of historical written works, not as individual titles each sold by a particular publisher. The work 紅樓夢/红楼梦 (Dream of the Red Chamber), for example, is available from many publishers in various editions, even translated into different languages. Your company's executives now wish to make individual titles for sale. Booker's domain model will need to be updated, and new business logic added.

Domain Model

Each individual book release is assigned an International Standard Book Number (ISBN) to identify the title commercially. Similarly periodicals are issued an International Standard Serial Number (ISSN) for identification. Booker so far has identified historical works merely by title; you must now update the domain model to capture an ISBN or ISSN identifier.

Data Layer

Update the data layer to support storage and lookup of publication ID.

In order for Booker to sell books, it will need to be able to keep track of stock quantities. Add the capability of storing the stock of books to PublicationRepository.

Business Logic Layer

Now you can update the application business logic so that Booker can begin to function as a bookstore.

Presentation Layer

Add a purchase command to allow a user to purchase a book. With this command a command-line parameter --isbn will indicate the ISBN of the book to purchase. Purchasing will lower the quantity in stock of the identified book by one. Display to the user the success of the purchase operation, along with the remaining stock.

Option Alias Description
list Lists all available publications.
load-snapshot Loads the snapshot list of publications into the current repository.
purchase Removes a single copy of the book identified by ISBN from stock.
--help -h Prints out a help summary of available switches.
--isbn Identifies a book, for example for the purchase command.
--locale -l Indicates the locale to use in the program, overriding the system default. The value is in language tag format.
--name -n Indicates a filter by name for the list command.
--type -t Indicates the type of publication to list, either book or periodical. If not present, all publications will be listed.

See Also

References

Acknowledgments