Visitor design pattern: can my visitor returns a Promise or should I create a new interface

130 Views Asked by At

I am now using a Visitor pattern where I have 2 visitors using the same interface returning T. It basically looks like the schema below, but my visitor returns something.

I would like to change the return type of one of my visitor to return a Promise.

Should I create a new interface for this issue?

enter image description here

2

There are 2 best solutions below

0
Dennis Kats On BEST ANSWER

If you want to make use of async/await, I think it makes sense to create a new interface called AsyncVisitor. Every visitor you implement should, in a sense, be thought of as its own "virtual" function on an enumeration of types. However, in JavaScript, Function and AsyncFunction are two inherently different types of functions, where the latter may suspend execution and must always return a Promise. Therefore, it doesn't make sense to have one visitor interface to represent both regular and async functions.

While you could hypothetically implement your promise-based Visitor as just Visitor<Promise<T>> and async/await will still work, your interface would then mix and treat Function and AsyncFunction as interchangeable types, which can be unexpected if you're doing some kind of metaprogramming.

In other words, I think your interfaces should look something like this:

interface Visitor<T> {
  visitElementA(e: ElementA): T;
  visitElementB(e: ElementB): T;
}

interface AsyncVisitor<T> {
  visitElementAAsync(e: ElementA): Promise<T>;
  visitElementBAsync(e: ElementB): Promise<T>;
}

interface Element {
  accept<T>(v: Visitor<T>): T;
  acceptAsync<T>(v: AsyncVisitor<T>): Promise<T>;
}
0
Lana James On

Ok, I just found this post: Java - Multiple visitor patterns for the same class structure

I needed to change my visitor return type:

Visitor1<Type1>

and

Visitor2<Promise<Type2>>