Using Visitor design pattern with Typescript and Angular

Frontend Engineer

Singapore. 22 July 2020 - talk.js July 2020

About me

Hi, My name is Trung 😊

  • Experienced FE engineer, specialised in branding, interactive application
  • Lead Frontend @Zyllem
  • Community Leader @Angular Vietnam
  • Blogger

Agenda

  • Use case

  • What's Visitor pattern?

  • Architecture and Design

  • Before Visitor pattern

  • After Visitor pattern

  • Pros and cons

  • Code demo

  • Q&A

Use case

In my application, I have a map view that displaying a route which contains:

 

  1. A few places on sequence, such as 1 -> 2 > 3 -> 4. Let call it a Point.
  2. A current driver’s location. Let call it a real-time/live location.
  3. A location where the route is started (noted that it isn’t the first point that I mention above). Let call it a Start location.

Behavior

Each of them will have the behaviors:

 

  • Display with a different icon on the maps.
  • Show a different message when hovering over.
  • Upon click/ mouseover/ mouse out events, do something.

 

Output

What is Visitor pattern?

Visitor is a behavioral design pattern that allows adding new behaviors to existing class hierarchy without altering any existing code.

You will see it in action very soon.

Benefit of visitor pattern

If you have multiple concrete classes that inherit from the same base class, or implement the same interface. You should consider using visitor pattern. It will save you from dozens of if-else block or switch/case and typecasting.

Architecture and Design

API Data Structure

Typescript Class Structure

  • ​CustomMarker - abstract class
  • PointMarker

  • StartLocationMarker

  • RealTimeLocationMarker

CustomMarker

Visitor Interface

The CustomMarkerVisitor interface declares a set of visiting methods that correspond to the number of concrete CustomMarker classes.

The signature of a visiting method allows the visitor to identify the exact class of the component that it's dealing with.

CustomMarker concrete class

For each concrete class, you will have to implement the accept method, because it is defined as an abstract method.

 

CustomMarker concrete method

Concrete class may have special methods that don't exist in their base class or interface. The Visitor is still able to use these methods since it's aware of the component's concrete class.

Concrete Visitor

A concrete CustomMarkerVisitor implement several versions of the same algorithm, which can work with all concrete CustomMarker classes. Think about it as a behavior that each concrete CustomMarker need to have such as click, double click, mouse over, mouse out. 

 

For each behavior, we will have a corresponding visitor to handle.

Generate CustomMarker

Life without visitor pattern

Alternative to switch/case

  • If else
  • Function factory

Life with Visitor Pattern

You see how we still can access to markerData variable on the callback of the mouseover despite the addMarkerToMap has been finished executing.

It is JavaScript Closure.

How does this even work?

Code demo

Pros

  • Reduce the number of doing switch/case for each behavior, see my code comparison table below. You will understand.
  • If I introduce a new type of CustomMarker, what I need to do is to update the CustomMarkerVisitor with a new method. The compiler won't build until I come to every implementation of CustomMarkerVisitor to implement it properly with the new method.  So that I will not afraid of missing behavior.

 

Cons

1. Not so easy for a junior developer to pick it up.

2. Too many boilerplate, even if you don't want your concrete class to have a specific behavior. You are forced to implement it.

 

 

Source code and article

Live demo

Blog post

Q&A

Thank you!

Made with Slides.com