Edit Page

Lab 11: Template Method Design Pattern

The goal of this lab is to use the template method design pattern to solve a real-world problem.

Design patterns are proven solutions to solve recurring design problems to design flexible and reusable object-oriented software. That is it, objects that are easier to implement, change, test and reuse. Behavioral pat­terns deal with the communication between objects and structuring the responsibilities between objects to keep­ them extensible, flex­i­ble and efficient.

The template method design pattern is one of the twenty-three well-known Gang of Four (GoF) design patterns. It is classified under the category of behavioral patterns. The template method is a method in an abstract superclass that acts as skeleton for an algorithm and allows concrete subclasses to define the behavior of these steps without changing their order.

Instead of implemeting the algorithm and define all required steps in each concrete subclass in multiple places, we create one single template method and define hooks inside it. Concrete/subclasses can define the behavior of these hooks when exetnding the superclass that contains the template method.

In this lab, we will work on creating a system for a financial service that executes some sensitive transactions. These transactions need to be protected by a unique password that can only be used once.

One-time passwords are additional security credentials that can be time based (TOTP) or counter based (HTOP). In order to execute a protected-transaction such as transfer, withdraw, and pay, a Time-based One-Time Password (TOTP) is generated and sent to the user. This TOTP changes after a set period (e.g., 60 seconds or 10 minutes).

Objectives

In this lab you will

  1. understand a real-world scenario and choose when to apply the appropriate design pattern.
  2. design and implement the template method design pattern.
  3. learn how to send an email from your application in Java.
  4. learn how to generate a time-based one-time password (TOTP), cache it, and validate it.

Requirmenet and Tools

Getting Started

1. Import the starter project at https://gitlab.com/cpit252/lab-10.

To compile and run the program, use your IDE or from the command line, run:

mvn compile

2. Create a Google Account

You also need to create an email account to send the receipt as an email message. You can create a new Google Account and enable the Less secure app access in your Google Account for sending emails from the Java program.

  1. Go to your Google Account Settings. Google Account Settings
  2. Click on Security. Google Account Settings
  3. Click on Less Secure App Access and turn it on. Google Account Settings

3. Store your Google Account’s username and password in the environment variables

You should avoid storing your username and password in the source code as hardcoded values. Instead, you should use environment variables. This program makes use of two environment variables: email and password. Create and set the values of these two environment variables. If you do not know how to set environment variables, please refer to the Environment Variables notes under Miscellaneous.

Problem Statement

A developer is working on a system for a financial service that executes some sensitive transactions. These transactions need to be protected by a Time-based one-time password (TOTP) that can only be used once. Upon executing a protected transaction (e.g., transfer, bill payment, etc.), the system will generate a one-time password (OTP) and email it to the user for verification. If the user enters the correct TOTP within the allowed time-frame, then the transaction can be executed.

The developer started by adding a TOTP protection for the transfer transaction as follows:


public class Transfer {

    private String accountNumber;
    private double amount;

    public Transfer(String accountNumber, double amount) {
        this.accountNumber = accountNumber;
        this.amount = amount;
    }

    public  boolean transferTransaction(User user) {
        // 1. send a one-time-password (OTP)
        sendOTP(user.getEmail());
        // 2. validate the OTP
        if (validateOTP(user.getEmail())) {
            // 3. Show a confirmation dialog
            if (showDialog()) {
                // 4. Perform/execute the transaction
                boolean result = perform(user);
                // 5. Show the close dialog
                closeDialog();
                // 6. Return the status of executing the transaction
                return result;
            }
        }
        return false;
    }
    public boolean showDialog() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Transferring money? (y|n) ");
        String answer = scanner.next();
        if (answer.contains("y")) {
            return true;
        }
        return false;
    }

    public boolean perform(User u) {
        simulateNetworkLatency();
        System.out.println("Transferring: SAR " + this.amount + " was sent to " + this.accountNumber);
        return true;
    }

    
    public void closeDialog() {
        System.out.println("Closing the Transfer dialog.");
    }
}

and later added two more classes for new transactions: “pay bills” and “increase daily limit”. These two classes also need to be TOTP protected.

At this point, she noticed that all three classes have a lot of similar code. While the code for executing the actual transaction is entirely different in all classes, the code for sending a TOTP, validating it, showing a transaction dialog, and closing the dialog is almost identical.

She wanted a better solution to get rid of the code duplication, leaving the algorithm’s steps and order as it is. The developer’s goal is to build an extensible system. She thought of using the Template design pattern to break down the algorithm into a series of steps/methods, and place the series of calls to these methods inside a single template method.

Questions:

  1. Complete the implementation of the template method design pattern as shown in the code above?
  2. Explain how the template design pattern enables you to enforce a fixed sequence of calls to the methods in your algorithm and override some of them?

Deliverables and Submission

Extra Task [Optional]

  • Currently, the TOTP is sent via email. Add additional method of delivering the TOTP using the strategy design pattern.
  • Add JUnit tests.
  • If you are done with this activity, you may upload/push your code into a source code repository (e.g., GitHub, GitLab), add a README.md file and enable a continous integreation tool such as Travis.ci to automatically run your JUnit test upon code changes. You may also embed the status image/badge that shows the status of your build and test (passing/failing) into your README file (e.g., passing status image and failing status image)

You may refer to adding continuous integration (CI) under miscellaneous for more information.