COMP2511 Extras

The following are topics that are no longer in the course and NOT examinable but if you were interested, you are free to check out!

State Pattern

* Not examinable

State Pattern

What is it?

Behavioural design pattern that allows an object to alter its behaviour when its internal state changes.

 

When should we use this pattern?

  • System can be modelled by a finite state machine (states, conditions for each transition, initial state)
  • Behaviour differs depending on the current state
  • Player has methods that can change its state
  • Behaviour of Player changes based on its state
    • Music is played in the PlayingState 
    • Music is paused in the ReadyState
    • Video Player is locked in the LockedState

State Pattern

Structure

State Pattern

Find out more at State (refactoring.guru)

Visitor Pattern

* Not examinable

Motivation

How can I add functionalities to legacy systems without altering the existing codebase too much?

The Visitor pattern suggests that you place the behaviour into a separate class, instead of trying to integrate it into existing classes

Visitor Pattern

What is it?

Behavioural design pattern that allow algorithms and objects that the algorithms operate on to be separated
 

Benefits

  • OCP: introduce behaviour to classes without changing their implementation.
  • SRP: functionality and data in an object can be separated


When to use?

New operations need to be added to all elements of an existing object structure

 

UML Diagram

  • Element classes must have an accept function that invokes the visit function of the Visitor
  • The Visitor interface declares a set of visiting methods   

Exercise

Visitor Pattern

Template Pattern

* Not examinable

Template Pattern

What is this?

Behavioural design pattern that defines the skeleton of an algorithm in the superclass but lets subclasses override specific steps without changing its structure. 

 

Why use it?

Let clients extend only particular steps of an algorithm, but not the whole structure 

 

What does it fix?

When you have several classes that contain almost identical algorithms with some minor differences.

Template Pattern

  • AbstractClass: Declares methods that act as steps of an algorithm, and the templateMethod() which calls these methods in a specific order

 

  • ConcreteClass: Can override all the steps, but not the template method itself
public abstract class AbstractClass {
    // Template Method
    public final void executeAlgorithm() {
        step1();
        step2();
        step3();
    }

    // Abstract steps to be implemented by subclasses
	public abstract void step1();
    public abstract void step2();
    public abstract void step3();
}

Abstract Class

Concrete Class

public class ConcreteClass extends AbstractClass {
    @Override
    protected void step1() {
        // Custom implementation for step 1
    }

    @Override
    protected void step2() {
        // Custom implementation for step 2
    }

    @Override
    protected void step3() {
        // Custom implementation for step 3
    }
}

Template Pattern

Template Pattern

In a cafe, we have the task of crafting different beverages. Each type of beverage such as coffee, tea and milk tea follow a similar structure but differ in behaviour at each step.

For example all beverages have the structure:

  1. Boil water
  2. Brew
  3. Pour in cup
  4. Add condiments
  5. Add straw (optional)

Use the template pattern to refactor this code.

Template Pattern

Adapter Pattern

* Not examinable

Adapter Pattern

What is this?

Structural design pattern that allows objects with incompatible interfaces to collaborate.

 

Why use it?

Often used to make existing classes (APIs) work with a client class without modifying their source code

 

What does it fix?

E.g. You have a legacy system that uses one type of interface and a new system that uses another.

Adapter Pattern

  • Adapter is able to work with the client and the service. 
    • Implements the client interface while wrapping the service object
  • ClientInterface describes a protocol that other classes must follow to be able to collaborate with the Client

Adapter Pattern

We have a scenario involving round holes and blocks, and square blocks that need to be adapted to fit into round holes.

 

Our task is to implement the Adapter Pattern to allow square blocks to be used with round holes.

Builder Pattern

* Not examinable

What is it?

Creational design pattern that lets you construct complex objects step by step.

 

Allows us to produce different types and representations of an object using the same construction process
 

Benefits

  • SRP: You can isolate complex construction code from business logic of the product
  • Avoid repetition: Can reuse the same construction code when building various representations of products 

 

Builder Pattern

When to use?

Use to get rid of "telescoping constructor"

 

Say we have a monstrous constructor...

Car car = new Car(id, brand, null, color, 
	nbrDoors, null, weight, null);

What happens if we don't require all the fields for this class? 

Builder Pattern

When to use?

Use to get rid of "telescoping constructor"

 

Say we have a monstrous constructor...

new Car(id, brand, model);
new Car(id, screenType, weight, height);
new Car(id, brand, model, color, nbrDoors);
new Car(id, brand, screenType, weight, height);

A solution is to create several overloaded constructors, but now we have too many constructors

Builder Pattern

Builder Pattern

Builder Pattern suggests to extract the object construction or creation out of its own class and move it to separate classes called builders. 

Builder Pattern

Builder Pattern

How could you extend this solution to add ToyTrains and a ToyTrainBuilder to the system?

This would require a builder interface and separate concrete builders, similar to the lecture examples

How could you extend this solution to add ToyTrains and a ToyTrainBuilder to the system?

TrainBuilder

ToyTrain

Builder

Builder Pattern

What we coded up was a relatively simple version of the Builder Pattern. 

 

Going back to our cars, what happens if we find that for similar cars we are always reusing the same steps to construct the car? 

Car car = new CarBuilder()
	.id (2122)
	.brand("Bugatti")
    .model("Chiron")
    .color("Blue")
    .nbrDoors(2)
    .engine("8L")
    .height(115)
    .build();
Car car = new CarBuilder()
	.id (2123)
	.brand("Bugatti")
    .model("Divo")
    .color("Blue")
    .nbrDoors(2)
    .engine("8L")
    .height(115)
    .build();
Car car = new CarBuilder()
	.id (2123)
	.brand("Bugatti")
    .model("Divo")
    .color("Black")
    .nbrDoors(2)
    .engine("8L")
    .height(115)
    .build();

Builder Pattern

Introducing the Director which defines the order in which we should call the construction steps so that we can reuse specific configurations of the products we are building.

public class Director {
  public void buildBugatti (CarBuilder builder) { 
  	builder.brand("Bugatti") 
    	.color("Blue") 
        .nbrDoors (2) 
        .engine ("8L")
  		.height(115);
}

Generics

* Not examinable

class IntegerBox {
    private Integer value;

    public void shoutValue(Integer value) {
        System.out.println(value.toString().toUpperCase + "!");
    }
}
class StringBox {
    private String value;

    public void shoutValue() {
        System.out.println(value.toString().toUpperCase + "!");
    }
}

IntegerBox

StringBox

What are some design problems with this code?

  • Duplication of code: both classes have exact same functionality, just different types
  • Scalability issues, we have to write more classes for more types

Generics

What is it?

Style of programming that allow types to be used as a parameter to methods, classes and interfaces.

Why would you use it?

  • Allow one implementation to work for a collection of different types
  • Offer strong type checking at compile time

Generics

public class Box<T> {
    
    private T value; 
    
    public Box(T value) {
        this.value = value;
    }
    
    public void setValue(T value) {
        this.value = value;
    }
    
    public T getValue() {
        return value;
    }
}
public class Box<T, S> {
    
    private T value1; 
    private S value2; 
    
    public Box(T value1, S value2) {
        this.value1 = value1;
        this.value2 = value2;
    }
    
    public void setValue(T value1, S value2) {
        this.value1 = value1;
        this.value2 = value2;
    }
    
    public T getValue1() {
        return value1;
    }
    
    public S getValue2() {
        return value2;
    }
}

Generics

Inside src/stack, there are a series of stubs for a Stack class which takes in a generic type. There are a series of tests inside StackTest.java which currently fail.

 

Implement the methods so that the tests pass, using an ArrayList to store the internal data structure.

Iterators vs. Iterables

Iterable

  • Iterable are objects that can be iterated over. 
  • Provides abstraction that provides a way to get to an Iterator
public interface Iterator<T> {
    boolean hasNext();
    T next();
    void remove();
}

Iterator

  • Are the actual mechanism to iterate over elements
  • Provides methods to traverse a collection and access its elements one by one. 
public interface Iterable<T> {
    Iterator<T> iterator();
}

Iterator

public interface Iterator<T> {
    boolean hasNext();
    T next();
    void remove();
}
  • hasNext(): Returns true if iteration has more elements after
  • next(): Returns next element of iteration
  • remove(): Removes from the collection the last element return by the iterator

Generics

public static Integer sumStack(Stack<? extends Integer> stack);
  • What does the <? extends Type>  and <? super Type> mean?
  • extends: the parameterised type must be the type or subclass of the given type
  • super: the parameterised type must be the type or superclass of the given type
  • What is ?
  • ? is called a wildcard and represents an unknown type. Provides flexibility for methods that accept a range of types

Let's say T = Fruit

Then for List<? extends Fruit>, we can read any object in list that is fruit subclass (Strawberry, Banana) and treat it like Fruit

PECS in Generics

List<? extends T> src

List<? super T> dest

Say T = Strawberry.

  • ? super Strawberry = Any container that can accept strawberries: a BerryBasket, a FruitBasket, or an ObjectBox.

  • You cannot add strawberries to a List<WildStrawberry> — that’s more specific, not general enough.

COMP2511 Extras

By rebeccahsu

COMP2511 Extras

  • 174