Implementing Use Cases

The Entity-Control-Boundary Pattern

The Entity-Control-Boundary Pattern (ECB) is a variation of the Model-View-Controller Pattern.

Entity, Control, and Boundary are class stereotypes, but UML has some special icons to represent them:

 

Here's the same diagram without the special icons:

Entities are objects representing system data: Customer, Transaction, Cart, etc.

Boundaries are objects that interface with system actors: user interfaces, gateways, proxies, etc.

Controllers are objects that mediate between boundaries and entities. They orchestrate the execution of commands coming from the boundary.

ATM Example

The Hexagonal Architecture Pattern (aka Ports & Adapters)

The Hexagonal Architecture partitions objects into one of three nested hexagons: Entities in the inner hexagon, controllers in the middle hexagon, boundaries in the outer hexagon, and actors outside of the outer hexagon:

Actors interact with boundary objects.

Boundary objects issue commands to controller objects.

Controller objects may send queries back to the boundary objects to get more information from the actors.

Controllers then update entities.

Boundaries refresh themselves as needed to reflect changes among the entities.

Mapping to MVC

We can map the inner hexagon filled with entities to the Model role in the Model-View-Controller Pattern. Controllers obviously map to Controllers, and boundaries, at least boundaries that interact with users, map to views.

The Hexagonal architecture has several nice features.

1. It doesn't distinguish between user interfaces and interfaces to other types of actors such as servers and devices.

2. We can view a boundary object as any object that happens to implement an interface required by a controller. This interface can be viewed as a port on the boundary of the middle hexagon. This makes testing easy since we can implement boundary objects as real actor interfaces or as mock actors.

The Use Case Controller Pattern

Developers often have trouble pointing to the place in the design where a particular use case is implemented. This problem can be mitigated by identifying each use case with a specific controller object. In this case the controller is called a use case controller.

A Framework

We can take this one step further with a framework:

Here's a sketch of a Java implementation:

abstract class Model extends Observable implements Serializable { }

interface Oracle {
   String ask(String query);
}

abstract class Boundary implements Oracle, Observer {
   protected Model myModel;
   public Boundary(Model m) {
      myModel = m;
      myModel.subscribe(this);
   }
}

abstract class UseCaseController implements Oracle {
   protected Model myModel;
   abstract public String execute(Oracle caller, String cmmd)
   throws Exception;
}

Customizing the Framework

We can customize the framework into our ATM machine:

The business Package

The presentation Package

 

A particular use case controller implements the scenarios of the use case:

class TransferFunds extends UseCaseController {
   private Bank bank; // my collaborator
   private String amount, source, destination; // info from boundary
   // called by bank:
   public String ask(String query) {
      if (query.eqauls("Source?")) {
         return source;
      } else if (query.equals("Destination?")) {
         return destination;
      } else if (query.equals("Amount?")) {
         return amount;
      } else {
         return "unknown";
      }
   }
   // called by boundary:
   public String execute(Oracle caller, String cmmd) throws Exception {
      source = caller.ask("Source?");
      destination = caller.ask("Destination?");
      amount = caller.ask("Amount?");
      String response = bank.ask("transfer funds");
      if (!response.equals("success")) {
         throw new Exception(response);
      }
      return response;
   }
}

 

References

The Entity-Control-Boundary Pattern.

Mock Objects

The Hexagonal Architecture

The Use Case Controller Pattern