Lab 05 - Factory Method, Option, Lazy Evaluation

Factory method

The motivation of using factory method is that

  1. A single method (or a very few number of methods) that is (are) flexible enough to return us the desired instance based on the argument used.

  2. A way to detect and handle invalid argument during object instantiation.

For example, below is an example about the factory method in Task

abstract class Task {
    private int amount;

    public static Task of(int type, int amount) {
        switch (type) {
            case 0:
                return new DepositTask(amount);
            case 1:
                return new WithdrawalTask(amount);
            case 2:
                return new CurrencyExchangeTask(amount);
            case 3:
                return new TransferTask(amount);
            case 4:
                return new LoanTask(amount);
            default:
                throw new IllegalArgumentException("No such task");
        }
    }
}

Now the task creation logic has been unified to Task.Of(type, amount).

Singleton

Singleton is a class that has at most one active instance at any point of time. There are three ways to handle the singleton instantiation:

  1. Destroy or deactivate the current active instance by overwriting the static reference.

  2. Reset the current active instance and discard the new instance.

  3. Block the creation of new instances by failing silently.

The following code serves as an example for singleton pattern.

Caching

Caching is to store the unique/special values as static fields in the class. For the caching to work, the variable should hold a constant value (by adding final keyword).

For example, we want to cache the special value ORIGIN in a 2-D plane in our Factory method.

Error-Handling

Throwing exceptions is not recommended, this is because:

  1. We need to write lots of try-catch blocks if there are many potential errors.

  2. Throwing exceptions is an overkill for Minor errors that can be easily mitigated.

  3. Unhandled exceptions can crash the program, but we may want to salvage some partially correct output (example: you need to multiply one million pairs of n×nn\times n matrices and the 999999-th operation crashes your program :O).

Thus, the idea to handle errors without using exception it that: overwritting the invalid data with harmless and useless values. More specifically, in our factory method, we can deal with these by again returning instances with special values (the cached values).

For example,

Exercise 5 Review

  1. Choose the most flexible type to declare the special meaning variables. For example, NONE should be declared using unbounded wildcard.

Maybe

What on earth is Maybe?

  • Context: We wish to search for something but we are not sure if it exists.

  • How to indicate that the item we are looking for does not exist?

    • "Classic" approach: set foundItem = null

    • However, null has two meanings!

      • the target isntance does not exist, or

      • the target isntance does exist but has a default (undefined) value, e.g., in this case, null is a valid value for an actual item.

      • Analogy: \varnothing — a set containing no elements; {}\{\varnothing\} — a set containing \varnothing as an element.

    • Self-contradiction: null can be used to indicate "not found", but what if we are really looking for null?

    • Here it comes! Maybe<T>: a wrapper for an item that may or may not exist.

    • Contradiction-free now:

      • None — item not found;

      • Some(null) — target item null and is found

      • What if we are searching for None?

      • Return None if not found, Some(None) otherwise

    • In Java Standard, Maybe<T> is called Optional<T>.

map and flatMap

  1. Draw the pipeline to help you visualize the boxing process.

  2. To define the wildcard to the parameter, try to relax it!

Lab Sheet

1

Q2

After rewriting

2

Q3

The code after modifying is:

3

Q5

The code after modifying is:

Tips

  1. When doing flatMap and map questions, always think about the situations when your arguments are Maybe.none(), will your final return only Maybe.NONE as expected?

Last updated