Static Factories are Great!

Every now and then I jump on classes with multiple constructors or classes that are rigorous to work with. Let alone not being able to mock part of their components and at the end being forced to use reflection for testing (mockito based, old school, you choose).

Imagine a Producer class that you use for Kafka. A class that provides you with some abstraction on sending messages.

package com.gkatzioura.kafka.producer;

import java.util.Properties;
import java.util.concurrent.ExecutionException;

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

@Slf4j
public class StrMessageProducer {

	private Producer<String,String> producer;
	private String topic = "test-topic";
	
	StrMessageProducer() {
		var kafkaProperties = new Properties();
		kafkaProperties.put("bootstrap.servers",System.getProperty("bootstrap.servers"));
		kafkaProperties.put("key.serializer",System.getProperty("key.serializer"));
		kafkaProperties.put("value.serialize",System.getProperty("value.serializer"));
		var kafkaProducer = new KafkaProducer<String,String>(kafkaProperties);
		this.producer = kafkaProducer;
	}

	public void send(String message) {
		var producerRecord = new ProducerRecord<String,String>(topic,null, message);
		try {
			var metadata = producer.send(producerRecord).get();
			log.info("Submitted {}",metadata.offset());
		}
		catch (InterruptedException |ExecutionException e) {
			log.error("Could not send record",e);
		}
	}
}

Apart from being an ugly class it is also very hard to change some of its components.

For example

  • I cannot use this class to post to another topic
  • I cannot use this class to use a different server configuration apart from the one on the properties
  • It’s difficult to test the functionality of the class since crucial components are created through the constructor

It’s obvious that the constructor in this case serves the purpose on creating a Kafka producer based on the system properties. But the responsibility of the class is to use that producer in order send messages in a specific way. Thus I will move the creation of the Producer from the constructor. Also because we might want to swap the topic used, I will also inject the topic instead of having it hardcoded.
By doing so we encourage dependency injection. We make it easy to swap the ingredients of the class however the execution would be the same.

package com.gkatzioura.kafka.producer;

import java.util.Properties;
import java.util.concurrent.ExecutionException;

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

@Slf4j
public class StrMessageProducer {

	private final Producer<String,String> producer;
	private final String topic;

	StrMessageProducer(Producer<String,String> producer, String topic) {
		this.producer = producer;
		this.topic = topic;
	}

	public void send(String message) {
		var producerRecord = new ProducerRecord<String,String>(topic,null, message);
		try {
			var metadata = producer.send(producerRecord).get();
			log.info("Submitted {}",metadata.offset());
		}
		catch (InterruptedException |ExecutionException e) {
			log.error("Could not send record",e);
		}
	}
}

But we still need the producer to be created somehow. This is where the factory pattern kicks in.

We shall add static factories in order to have instances of the StrMessageProducer class with different configurations.
Let’s add two factory methods
The first factory method would be based on system properties and the second on environment variables.

package com.gkatzioura.kafka.producer;

import java.util.Properties;
import java.util.concurrent.ExecutionException;

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

@Slf4j
public class StrMessageProducer {

	private final Producer<String,String> producer;
	private final String topic;

	StrMessageProducer(Producer<String,String> producer, String topic) {
		this.producer = producer;
		this.topic = topic;
	}

	public void send(String message) {
		var producerRecord = new ProducerRecord<String,String>(topic,null, message);
		try {
			var metadata = producer.send(producerRecord).get();
			log.info("Submitted {}",metadata.offset());
		}
		catch (InterruptedException |ExecutionException e) {
			log.error("Could not send record",e);
		}
	}

	public static StrMessageProducer createFromSystemPros() {
		var kafkaProperties = new Properties();
		kafkaProperties.put("bootstrap.servers",System.getProperty("bootstrap.servers"));
		kafkaProperties.put("key.serializer",System.getProperty("key.serializer"));
		kafkaProperties.put("value.serialize",System.getProperty("value.serializer"));
		var kafkaProducer = new KafkaProducer<String,String>(kafkaProperties);
		return new MessageProducer(kafkaProducer, System.getProperty("main.topic"));
	}

	public static StrMessageProducer createFromEnv() {
		var kafkaProperties = new Properties();
		kafkaProperties.put("bootstrap.servers",System.getenv("BOOTSTRAP_SERVERS"));
		kafkaProperties.put("key.serializer",System.getenv("KEY_SERIALIZER"));
		kafkaProperties.put("value.serialize",System.getenv("VALUE_SERIALIZER"));
		var kafkaProducer = new KafkaProducer<String,String>(kafkaProperties);
		return new MessageProducer(kafkaProducer, System.getProperty("MAIN_TOPIC"));
	}
}

You already see the benefits. You have a clean class ready to use as it is and you have some factory methods for convenience. Eventually you can add more static factories, some of them might also have arguments, for example the topic.

Also we can go one step further when we want to have multiple classes of MessageProducers and we want to utilise an interface. So we are going to introduce the MessageProducer interface which our StrMessageProducer class will implement. Also we are going to put the static factories to the interface.

So this will be our interface with the static factories.

package com.gkatzioura.kafka.producer;

import java.util.Properties;

import org.apache.kafka.clients.producer.KafkaProducer;

public interface MessageProducer {
	
	void send(String message);

	static MessageProducer createFromSystemPros() {
		var kafkaProperties = new Properties();
		kafkaProperties.put("bootstrap.servers",System.getProperty("bootstrap.servers"));
		kafkaProperties.put("key.serializer",System.getProperty("key.serializer"));
		kafkaProperties.put("value.serialize",System.getProperty("value.serializer"));
		var kafkaProducer = new KafkaProducer<String,String>(kafkaProperties);
		return new StrMessageProducer(kafkaProducer, System.getProperty("main.topic"));
	}

	static MessageProducer createFromEnv() {
		var kafkaProperties = new Properties();
		kafkaProperties.put("bootstrap.servers",System.getenv("BOOTSTRAP_SERVERS"));
		kafkaProperties.put("key.serializer",System.getenv("KEY_SERIALIZER"));
		kafkaProperties.put("value.serialize",System.getenv("VALUE_SERIALIZER"));
		var kafkaProducer = new KafkaProducer<String,String>(kafkaProperties);
		return new StrMessageProducer(kafkaProducer, System.getProperty("MAIN_TOPIC"));
	}

}

And this would be our new StrMessageProducer class.

package com.gkatzioura.kafka.producer;

import java.util.concurrent.ExecutionException;

import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;

@Slf4j
public class StrMessageProducer implements MessageProducer {

	private final Producer<String,String> producer;
	private final String topic;

	StrMessageProducer(Producer<String,String> producer, String topic) {
		this.producer = producer;
		this.topic = topic;
	}

	@Override
	public void send(String message) {
		var producerRecord = new ProducerRecord<String,String>(topic,null, message);
		try {
			var metadata = producer.send(producerRecord).get();
			log.info("Submitted {}",metadata.offset());
		}
		catch (InterruptedException |ExecutionException e) {
			log.error("Could not send record",e);
		}
	}

}

Let’s check the benefits

  • We can have various implementations of a MessageProducer class
  • We can add as many factories we want that serve our purpose
  • We can easily test the MessageProducer implementation by passing mocks to the constructors
  • We keep our codebase cleaner

 

Advertisement

Behavioural Design Patterns: Visitor

Our last pattern of the behavioural design patterns is going to be the visitor pattern.

We use the visitor pattern when we want to make it possible to define a new operation for classes of an object structure without changing the classes.

Imagine the scenario of a software that executes http requests to an api. Most http apis out there have certain limits and allow a specific number of requests to be executed per minute. We might have different class that executes requests and also takes into consideration the business logic with regards to the apis that they interact.
In case we want to inspect those calls and print some information or persist request related information to the database the visitor pattern might be a good fit.

We will start with the visitor interface.

package com.gkatzioura.design.behavioural.visitor;

public interface Visitor {
}

This interface will not specify any methods, however interfaces which extend it will contain methods visit with specific types to visit. We do this in order to be able to have loosely coupled visitor implementations (or even composition based visitors).

Then we shall implement the visitable interface.

package com.gkatzioura.design.behavioural.visitor;

public interface Visitable {

     void accept(T visitor);

}

Based on the above we shall create our request execution classes which are visitable.

package com.gkatzioura.design.behavioural.visitor;

public class LocationRequestExecutor implements Visitable {

    private int successfulRequests = 0;
    private double requestsPerMinute = 0.0;

    public void executeRequest() {
        /**
         * Execute the request and change the successfulRequests and requestsPerMinute value
         */
    }

    @Override
    public void accept(LocationVisitor visitor) {
        visitor.visit(this);
    }

    public int getSuccessfulRequests() {
        return successfulRequests;
    }

    public double getRequestsPerMinute() {
        return requestsPerMinute;
    }

}
package com.gkatzioura.design.behavioural.visitor;

public class RouteRequestExecutor implements Visitable {

    private int successfulRequests = 0;
    private double requestsPerMinute = 0.0;

    public void executeRequest() {
        /**
         * Execute the request and change the successfulRequests and requestsPerMinute value
         */
    }

    @Override
    public void accept(RouteVisitor visitor) {
        visitor.visit(this);
    }

    public int getSuccessfulRequests() {
        return successfulRequests;
    }

    public double getRequestsPerMinute() {
        return requestsPerMinute;
    }
}

And then we shall add the visitor interfaces for these type of executors

package com.gkatzioura.design.behavioural.visitor;

public interface LocationVisitor extends Visitor {

    void visit(LocationRequestExecutor locationRequestExecutor);
}
package com.gkatzioura.design.behavioural.visitor;

public interface RouteVisitor extends Visitor {

    void visit(RouteRequestExecutor routeRequestExecutor);
}

The last step would be to create a visitor that implements the above interfaces.

package com.gkatzioura.design.behavioural.visitor;

public class RequestVisitor implements LocationVisitor, RouteVisitor {

    @Override
    public void visit(LocationRequestExecutor locationRequestExecutor) {

    }

    @Override
    public void visit(RouteRequestExecutor routeRequestExecutor) {

    }
}

So let’s put em all together.

package com.gkatzioura.design.behavioural.visitor;

public class VisitorMain {

    public static void main(String[] args) {
        final LocationRequestExecutor locationRequestExecutor = new LocationRequestExecutor();
        final RouteRequestExecutor routeRequestExecutor = new RouteRequestExecutor();
        final RequestVisitor requestVisitor = new RequestVisitor();

        locationRequestExecutor.accept(requestVisitor);
        routeRequestExecutor.accept(requestVisitor);
    }
}

That’s it! You can find the sourcecode on github.

Behavioural Design Patterns: Template method

Previously we used the strategy pattern to in order to solve the problem of choosing various speeding algorithms based on the road type. The next behavioural design pattern we are going to use is the template method.
By using the template method we define the skeleton of the algorithm and the implementation of certain steps is done by subclasses.

Thus we have methods with concrete implementations, and methods without any implementation. Those methods will be implemented based on the application logic needed to be achieved.

Imagine the case of a coffee machine. There are many types of coffees and different ways to implement them, however some steps are common and some steps although they vary they also need to be implemented. Processing the beans, boiling, processing the milk, they are all actions that differ based on the type of coffee. Placing to a cup and service however are actions that do no differentiate.

package com.gkatzioura.design.behavioural.template;

public abstract class CoffeeMachineTemplate {

    protected abstract void processBeans();

    protected abstract void processMilk();

    protected abstract void boil();

    public void pourToCup() {
        /**
         * pour to various cups based on the size
         */
    }

    public void serve() {
        processBeans();
        boil();
        processMilk();
        pourToCup();
    }

}

Then we shall add an implementation for the espresso. So here’s our espresso machine.

package com.gkatzioura.design.behavioural.template;

public class EspressoMachine extends CoffeeMachineTemplate {

    @Override
    protected void processBeans() {
        /**
         * Gring the beans
         */
    }

    @Override
    protected void processMilk() {
        /**
         * Use milk to create leaf art
         */
    }

    @Override
    protected void boil() {
        /**
         * Mix water and beans
         */
    }
}

As you see we can create various coffee machine no matter how different some steps might be.
You can find the sourcecode on github.

Behavioural Design Patterns: Strategy

Previously we used the state in order to add some functionality to an application based on the user state. Our next behavioural design pattern is Strategy.
The strategy pattern enables us to select an algorithm at runtime. Based on the instructions our program will pick the most suitable algorithm instead of implementing an algorithm directly. This makes our codebase more flexible and keep it clean from any extra logic.

Our example shall evolve around vehicles and the speeding that is allowed based on the type of road. For example if a vehicle is on a four lane road the speed would be way different than being on an urban area road.
So we are actually going to implement the strategy patterns with regards to speeding.

We will start with the speeding interface.

package com.gkatzioura.design.behavioural.strategy;

public interface Speeding {

    Double adjustSpeed(Double currentSpeed);

}

Then we shall create some implementations based on the road type.
The four lane speeding implementation adjusts the speeding when driving on a four lane.

package com.gkatzioura.design.behavioural.strategy;

public class FourLaneSpeeding implements Speeding {

    private static final Double upperLimit = 50d;

    @Override
    public Double adjustSpeed(Double currentSpeed) {
        if(currentSpeed>upperLimit) {
            currentSpeed = upperLimit;
        }

        System.out.println("Speed adjusted at "+currentSpeed);

        return currentSpeed;
    }

}

The urban area speeding implementation adjusts the speeding when driving on a rural road.

package com.gkatzioura.design.behavioural.strategy;

public class UrbanAreaSpeeding implements Speeding {

    private static final Double upperLimit = 30d;

    @Override
    public Double adjustSpeed(Double currentSpeed) {
        if(currentSpeed>upperLimit) {
            currentSpeed = upperLimit;
        }

        System.out.println("Speed adjusted at "+currentSpeed);

        return currentSpeed;
    }

}

And then we shall create the vehicle class.

package com.gkatzioura.design.behavioural.strategy;

public class Vehicle {

    private Speeding speeding;
    private Double currentSpeed;

    public void drive() {

        speeding.adjustSpeed(currentSpeed);

        /**
         * Driving related actions.
         */
    }

    public void setSpeeding(Speeding speeding) {
        this.speeding = speeding;
    }

    public void setCurrentSpeed(Double currentSpeed) {
        this.currentSpeed = currentSpeed;
    }
}

As you can see the vehicle shall change its speeding strategy based on the road driving.
Let’s put them all together.

package com.gkatzioura.design.behavioural.strategy;

public class Strategy {

    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();

        vehicle.setCurrentSpeed(70d);
        
        vehicle.drive();
        
        /**
         * Changed route
         */
        
        vehicle.setSpeeding(new FourLaneSpeeding());

        vehicle.drive();

        /**
         * Changed route
         */
        
        vehicle.setSpeeding(new UrbanAreaSpeeding());

        vehicle.drive();
    }
}

That’s all for now! You can find the sourcecode on github.

Behavioural Design patterns: State

The state pattern deals with altering an object’s behaviour when its state changes.

Imagine the case of a class responsible for generating user interface based on the state. You got anonymous, logged-in and admin users.

We shall create an interface called GreetingState which defines the action of drawing a html text with a welcome message to the user. There is going to be a different implementation according to the states that we have.

package com.gkatzioura.design.behavioural.state;

public interface GreetingState {

    String create();

}

We shall implement the GreetingState for the anonymous user.

package com.gkatzioura.design.behavioural.state;

public class AnonymousGreetingState implements GreetingState {

    private static final String FOOTER_MESSAGE = "<p><Hello anonymous user!</p>";

    @Override
    public String create() {
        return FOOTER_MESSAGE;
    }

}

Then we shall implement the GreetingState for the logged in user. This one would create a personalised message.

package com.gkatzioura.design.behavioural.state;

public class LoggedInGreetingState implements GreetingState {

    private static final String FOOTER_MESSAGE = "<p><Hello %s!</p>";

    private final String username;

    public LoggedInGreetingState(final String username) {
        this.username = username;
    }

    @Override
    public String create() {
        return String.format(FOOTER_MESSAGE,username);
    }

}

And at last the admin Footer.

package com.gkatzioura.design.behavioural.state;

import java.util.Date;

public class AdminGreetingState implements GreetingState {

    private static final String FOOTER_MESSAGE = "<p><Hello %s, last login was at %s</p>";

    private final String username;
    private final Date lastLogin;

    public AdminGreetingState(final String username, Date lastLogin) {
        this.username = username;
        this.lastLogin = lastLogin;
    }


    @Override
    public String create() {
        return String.format(FOOTER_MESSAGE,username,lastLogin);
    }

}

The we shall create the stateui context.

package com.gkatzioura.design.behavioural.state;

import java.io.PrintWriter;

public class StateUIContext {

    private GreetingState greetingState;

    public void setGreetingState(GreetingState greetingState) {
        this.greetingState = greetingState;
    }

    public void create(PrintWriter printWriter) {
        printWriter.write(greetingState.create());
    }
}

Let’s put them all together.

package com.gkatzioura.design.behavioural.state;

import java.io.PrintWriter;
import java.util.Date;

public class StateMain {

    public static void main(String[] args) {

        StateUIContext stateUIContext = new StateUIContext();

        try(PrintWriter printWriter = new PrintWriter(System.out)) {
            stateUIContext.setGreetingState(new AnonymousGreetingState());
            stateUIContext.create(printWriter);
            printWriter.write("\n");
            stateUIContext.setGreetingState(new LoggedInGreetingState("someone"));
            stateUIContext.create(printWriter);
            printWriter.write("\n");
            stateUIContext.setGreetingState(new AdminGreetingState("admin",new Date()));
            stateUIContext.create(printWriter);
            printWriter.write("\n");
        }
    }
}

You can find the sourcecode on github.

Behavioural Design patterns: Observer

Observer is one of the most popular design patterns. It has been used a lot on many software use cases and thus many languages out there provide it as a part of their standard library.

By using the observer pattern we can tackle the following challenges.

  • Dependency with objects defined in a way that avoids tight coupling
  • Changes on an object changes its dependent objects
  • An object can notify all of its dependent objects

Imagine the scenario of a device with multiple sensors. Some parts of the code will need to get notified when new sensor data arrive and thus act accordingly. We will start by a simple class which represents the json data.

package com.gkatzioura.design.behavioural.observer;

public class SensorData {

    private final String sensor;
    private final Double measure;

    public SensorData(String sensor, Double measure) {
        this.sensor = sensor;
        this.measure = measure;
    }

    public String getSensor() {
        return sensor;
    }

    public Double getMeasure() {
        return measure;
    }
}

The we shall create the observer interface. Every class that implements the observer interface shall be notified once a new object is created.

package com.gkatzioura.design.behavioural.observer;

public interface Observer {

    void update(SensorData sensorData);

}

Next step is to create the observable interface. The observable interface will have methods in order to register the observers that need to get notified.

package com.gkatzioura.design.behavioural.observer;

public interface Observable {

    void register(Observer observer);

    void unregister(Observer observer);

    void updateObservers();

}

Now let us put some implementations.
The sensor listener will receive data from the sensors and notify the observers about the presence of data.

package com.gkatzioura.design.behavioural.observer;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class SensorReceiver implements Observable {

    private List data = new ArrayList();
    private List observers = new ArrayList();

    @Override
    public void register(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void unregister(Observer observer) {
        observers.remove(observer);
    }

    public void addData(SensorData sensorData) {
        data.add(sensorData);
    }

    @Override
    public void updateObservers() {

        /**
         * The sensor receiver has retrieved some sensor data and thus it will notify the observer
         * on the data it accumulated.
         */

        Iterator iterator = data.iterator();

        while (iterator.hasNext()) {

            SensorData sensorData = iterator.next();

            for(Observer observer:observers) {
                observer.update(sensorData);
            }

            iterator.remove();
        }
    }

}

The we will create an observer which shall log the sensor data received to database, it might be an influxdb or an elastic search you name it.

package com.gkatzioura.design.behavioural.observer;

public class SensorLogger implements Observer {

    @Override
    public void update(SensorData sensorData) {

        /**
         * Persist data to the database
         */

        System.out.println(String.format("Received sensor data %s: %f",sensorData.getSensor(),sensorData.getMeasure()));
    }

}

Let’s put the all together.

package com.gkatzioura.design.behavioural.observer;

public class SensorMain {

    public static void main(String[] args) {

        SensorReceiver sensorReceiver = new SensorReceiver();
        SensorLogger sensorLogger = new SensorLogger();
        sensorReceiver.register(sensorLogger);
        sensorReceiver.addData(new SensorData("temperature",1.2d));
        sensorReceiver.updateObservers();
    }
}

You can find the source code on github.

Behavioural Design patterns: Memento

The memento pattern is all about state. You use it when you want to restore the object to its previous state.
You have an object, you apply some actions and you are able to revert those actions and get the object in the various states it has been before.

Most of us implement various algorithms and sometimes we do need to evaluate em. Imagine having a program that evaluates trade decisions and you want to go to a previous state and check what would happen to the account balance if you change the formula, and then evaluate the account balance for each step.

The steps of the algorithm and what you should change will definitely vary. The memento pattern will assist us to our mission and help us do some fast in memory evaluation.

We will have a Memento object that contains the account balance.
Memento will represent the balance on different phases.

package com.gkatzioura.design.behavioural.memento;

public class Memento {

    private Double balance;

    public Memento(Double balance) {
        this.balance = balance;
    }

    public Double getBalance() {
        return balance;
    }
}

Then we will create the originator object. The originator will contain the current state. It can pass it back as a memento when we need to store it. Also we can use a memento object to it restore a certain state.

package com.gkatzioura.design.behavioural.memento;

public class Originator {

    private Double balance;

    public void setBalance(Double balance) {
        this.balance = balance;
    }

    public Double getBalance() {
        return balance;
    }

    public Memento saveToMemento() {
        return new Memento(balance);
    }

    public void restoreToState(Memento memento) {
        balance =  memento.getBalance();
    }
}

The last step is the CareTaker object, this will contain the history of our balance. The caretaker will fetch the object state during their various phases.

package com.gkatzioura.design.behavioural.memento;

import java.util.ArrayList;
import java.util.List;

public class CareTaker {

    private List mementoList = new ArrayList();

    public void add(Memento state){
        mementoList.add(state);
    }

    public Memento get(int index){
        return mementoList.get(index);
    }

}

So let’s put them all together.

package com.gkatzioura.design.behavioural.memento;

public class MementoMain {

    public static void main(String[] args) {

        Double balance = 20.1d;

        Originator originator = new Originator();
        originator.setBalance(balance);

        CareTaker careTaker = new CareTaker();

        careTaker.add(originator.saveToMemento());

        /**
         * Do a transaction
         */

        originator.setBalance(balance-2);
        careTaker.add(originator.saveToMemento());

        /**
         * Do a transaction
         */

        originator.setBalance(balance+4);
        careTaker.add(originator.saveToMemento());

        System.out.println(careTaker.get(0).getBalance());
        System.out.println(careTaker.get(1).getBalance());
        System.out.println(careTaker.get(2).getBalance());
    }
}

You can find the source code on github.

Behavioural Design Patterns: Mediator

Previously we had a look at the iterator pattern.

The mediator pattern is way different on what it tries to achieve. It is one of the behavioural patterns and its purpose is to alter the way objects communicate with each other. Instead of the objects communicating with each other directly the mediator will handle the objects interaction.

For example imagine the scenario of a financial exchange. You do want to trade and buy but you don’t buy directly from the one that makes the offer.
Instead the exchange is in the middle, in order for you to make the transaction.

People would like to sell and buy. This shall be facilitated by the exchange.
You got the order object.

package com.gkatzioura.design.behavioural.mediator;

public class Order {

    private String stock;
    private Integer quantity;
    private Double price;

    public String getStock() {
        return stock;
    }

    public void setStock(String stock) {
        this.stock = stock;
    }

    public Integer getQuantity() {
        return quantity;
    }

    public void setQuantity(Integer quantity) {
        this.quantity = quantity;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

}

The next object would be the financial entity that sells the stocks.

package com.gkatzioura.design.behavioural.mediator;

public class FinancialEntity {

    public boolean sell(Order order) {

        /**
         * Supposing the sale was successful return true
         */
        return true;
    }

}

Then we create the exchange object. We won’t get further into commissions but imagine that things can be way more complex. The exchange is actually our mediator.

package com.gkatzioura.design.behavioural.mediator;

public class Exchange {

    private FinancialEntity financialEntity;

    public Exchange(FinancialEntity financialEntity) {
        this.financialEntity = financialEntity;
    }

    public void serve(Order order) {

        /**
         * Choose the financial entity suitable for the order
         */
        financialEntity.sell(order);
    }

}

And the last step is creating the trader object.

package com.gkatzioura.design.behavioural.mediator;

public class Trader {

    private Exchange exchange;

    public Trader(Exchange exchange) {
        this.exchange = exchange;
    }

    public void buy(String stock,Integer quantity,Double price) {
        Order order = new Order();
        order.setStock(stock);
        order.setQuantity(quantity);
        order.setPrice(price);
        exchange.serve(order);
    }

}

As you can see the trader object is not interacting directly with the financial entity that provides the stocks.

Let’s put them all together in a main class.

package com.gkatzioura.design.behavioural.mediator;

public class Mediator {

    public static void main(String[] args) {

        final FinancialEntity financialEntity = new FinancialEntity();
        final Exchange exchange = new Exchange(financialEntity);
        Trader trader = new Trader(exchange);
        trader.buy("stock_a",2,32.2d);
    }
}

That’s it, you just used the mediator pattern for an exchange application! You can also find the source code on github.

Behavioural Design Patterns: Iterator

The iterator pattern is one of the most used patterns from the behavioural ones. Most of the times you use it without even noticing it. Supposing you have a container with elements and you want to traverse them. Iterating the elements might differ based on the container, retrieval method etc. By using the iterator pattern we can decouple the algorithms used by the containers, and the retrieval methods and abstract the iteration of the elements contained.

For example when it comes to retrieving paged data from a rest endpoint the iterator can help you to abstract it. Therefore you won’t expose the user with any information on how you retrieve the next batch of data.

I will make a new iterator interface similar the one provided by the java language.

package com.gkatzioura.design.behavioural.iterator;

public interface Iterator<T> {

    boolean hasNext();
    
    T next();
    
}

We will use the github jobs api since it is open to issue rest queries and search for jobs.
The first page is page zero.

https://jobs.github.com/positions.json?page=0.

We shall create a simple object which would contain the id, title and company information.

package com.gkatzioura.design.behavioural.iterator;

import java.util.UUID;

public class GitHubJob {

    private final UUID id;
    private final String company;
    private final String title;

    public GitHubJob(UUID id, String company, String title) {
        this.id = id;
        this.company = company;
        this.title = title;
    }

    public UUID getId() {
        return id;
    }

    public String getCompany() {
        return company;
    }

    public String getTitle() {
        return title;
    }
}

Our first step would be to create a repository witch shall fetch the data of the page specified.

package com.gkatzioura.design.behavioural.iterator;

import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.IOUtils;
import org.json.JSONArray;
import org.json.JSONObject;

public class GitHubJobsRepository {

    public static final String GITHUB_JOB_API = "https://jobs.github.com/positions.json?page=";

    public List<GitHubJob> fetch(int page) throws Exception {

        List<GitHubJob> gitHubJobs = new ArrayList<>();

        URL url = new URL(GITHUB_JOB_API+page);
        HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
        String response = IOUtils.toString(httpConnection.getInputStream(), Charset.defaultCharset());
        JSONArray jsonArray = new JSONArray(response);

        for(int i=0;i<jsonArray.length();i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            GitHubJob gitHubJob = new GitHubJob(
                    UUID.fromString(jsonObject.getString("id")),
                    jsonObject.getString("company"),
                    jsonObject.getString("title"));
            gitHubJobs.add(gitHubJob);
        }

        return gitHubJobs;
    }

}

What’s great with this api is that if you ask for a page that does not exists you get an empty json object, thus asking for a non existing page won’t give us an exception like 404, therefore no need for error handling for this case.

Now the interesting part is the iterator.

package com.gkatzioura.design.behavioural.iterator;

import java.util.ArrayList;
import java.util.List;

public class GitHubIterator implements Iterator<GitHubJob> {

    private List<GitHubJob> currentJobsPage = new ArrayList<>();
    private int page = 0;

    private final GitHubJobsRepository gitHubJobsRepository;

    public GitHubIterator(GitHubJobsRepository gitHubJobsRepository) {
        this.gitHubJobsRepository = gitHubJobsRepository;
    }

    @Override
    public boolean hasNext() {
        fetchPageIfNeeded();
        return currentJobsPage.size()>0;
    }

    @Override
    public GitHubJob next() {
        fetchPageIfNeeded();

        if(currentJobsPage.size()==0) {
            return null;
        }

        return currentJobsPage.remove(0);
    }

    private void fetchPageIfNeeded() {
        if(page == -1) {
            return;
        }

        if(currentJobsPage==null||currentJobsPage.size()==0) {
            try {
                currentJobsPage = gitHubJobsRepository.fetch(page);
                if(currentJobsPage.size()==0) {
                    page = -1;
                } else {
                    page++;
                }
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}

The iterator shall contain a page request from github. For each element requested one item shall be removed from the page. Once the page gets empty a new page shall be requested.

Whether the user asks for another element or if another element exists the code shall check if the current page is empty and if yes it will request for the next page. If we got an empty page this mean that there should not be any extra request to the iterator.

The next step would be to add a method to the repository which shall give back the github iterator.

public class GitHubJobsRepository {

...

    public Iterator<GitHubJob> iterator() {
        return new GitHubIterator(this);
    }

...
}

So let us sum up and iterate over all the entries.

package com.gkatzioura.design.behavioural.iterator;

public class IteratorExample {

    public static void main(String[] args) throws Exception {
        GitHubJobsRepository gitHubJobsRepository = new GitHubJobsRepository();

        Iterator<GitHubJob> gitHubJobIterator = gitHubJobsRepository.iterator();

        while (gitHubJobIterator.hasNext()) {
            GitHubJob gitHubJob = gitHubJobIterator.next();
            System.out.println(String.format(" id: %s title: %s company: %s",gitHubJob.getId(),gitHubJob.getTitle(),gitHubJob.getCompany()));
        }
    }

}

You can find the source code on github.

It is also worth referencing patterns we saw previously such as the interpreter, chain of responsibility and the command pattern.

Behavioural Design Patterns: Interpreter

Previously we had a look at the chain of responsibility and the command pattern. They do tackle different problems however they both delegate an action to another component, the command patterns always delegates the action, the chain of responsibility if the action cannot be handled it will be forward it to its successor.

We are going to switch context and check the interpreter pattern.
The interpreter pattern specifies how to evaluate custom languages.
The examples are limitless, for example the spel language for spring or even a sql like language.

We will keep things simple and create an interpreter for a simple query language only with select and where statements. This is not impossible in the real world, just thing about dynamodb and how simple its expressions are, the examples are countless.

So let’s start with our clause interface.

package com.gkatzioura.design.behavioural.interpreter;

public interface Clause{

}

I will implement the WhereClause

package com.gkatzioura.design.behavioural.interpreter;


public class WhereClause implements Clause {

    /**
     * Add values related to the where clause functions and expressions
     */

    public WhereClause() {
    }

    /**
     * Add functions for expressions for equals not equals etc.
     */

}

And the SelectClause

package com.gkatzioura.design.behavioural.interpreter;

import java.util.Optional;

public class SelectClause implements Clause {

    private Optional<WhereClause> optWhereClause = Optional.empty();

    public <T> T load(Class<T> valueType) {

        /**
         * Apply filter according to the where clause
         */
        if(optWhereClause.isPresent()) {

        }

        /**
         * Load data
         */

        /**
         * Serialize/Deserialize data based on the type
         * For example if you use jackson it will be:  new ObjectMapper().readValue("text",valueType);
         */


        return null;
    }

    public void setWhereClause(WhereClause whereClause) {
        this.optWhereClause = Optional.of(whereClause);
    }
}

The load function shall load our data based on the expression given.

Both clauses are linked together however the select clause can produce results even when ‘where’ statements have not been given whatsoever. In any case when it comes to loading the data the select clause will check and apply any filter statements that the where clause might have (if exists) and then return the data.
Let’s move to the interpreter specific parts

We will create the expression interface.

package com.gkatzioura.design.behavioural.interpreter;

public interface Expression {

    Clause interpret(String context);

}

The interpretation of the text given will give us back a clause.

We shall create the WhereExpression.

package com.gkatzioura.design.behavioural.interpreter;

public class WhereExpression implements Expression {

    @Override
    public WhereClause interpret(String context) {
        WhereClause whereClause = new WhereClause();
        /**
         * Parse the string and find any where statements ie. A=1 AND B!=2 and apply them.
         */

        return whereClause;
    }

}

And the Select Expression.

package com.gkatzioura.design.behavioural.interpreter;

public class SelectExpression implements Expression {

    @Override
    public SelectClause interpret(String context) {
        SelectClause selectClause = new SelectClause();

        /**
         * Parse text and check for expressions like `SELECT * FROM ` or `SELECT A,B,C FROM` .
         */

        return selectClause;
    }

}

The last step would be the query expression.

package com.gkatzioura.design.behavioural.interpreter;

public class QueryExpression implements Expression {

    @Override
    public SelectClause interpret(String context) {

        SelectClause selectClause = new SelectExpression().interpret(context);

        if(context.contains("WHERE")) {

            WhereClause whereClause = new WhereExpression().interpret(context);
            selectClause.setWhereClause(whereClause);
        }

        return selectClause;
    }

}

So let’s put them all together. We shall interpret a query which fetches a list of integers.

package com.gkatzioura.design.behavioural.interpreter;

public class Interpreter {

    public static void main(String[] args) {
        String selectionString = "SELECT b FROM foo WHERE a=1";
        Integer[] values = new QueryExpression()
                .interpret(selectionString)
                .load(Integer[].class);
    }

}

You can find the sourcecode on github.