Recall that in the Entity-Control-Boundary Pattern boundary objects interfaced with users, entity objects represented application data, and control objects executed commands from the boundary objects by interacting with the entity objects:

Recall also that each control object implemented one or more use cases.
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;
}
We can customize the framework into our ATM machine:



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;
   }
}
Complete the implementation of the ATM.