У меня есть следующий абстрактный класс Listener который инкапсулирует стандартный код для клиента. Тогда у меня может быть несколько слушателей для различных событий.
В качестве упражнения для самообучения я преобразовал это в функциональный способ.
- Это правильный способ функциональной реализации?
- Я пытаюсь избежать создания класса для каждого типа слушателя
- Должен ли я использовать тип или интерфейс. Поскольку это используется для проверки типов параметров, я не уверен, предпочтительнее ли один из них.
- Любые другие комментарии по реализации функционального способа (каррирование, функции высшего порядка)? Как новичок, я пытаюсь понять, применимы ли они здесь и как.
abstract class Listener {
abstract subject: string;
private client: Client;
abstract groupName: string;
protected ackTimeout = 5 * 1000;
abstract onMessage(data: any, msg: Message): void;
constructor(client: Client) {
this.client = client;
}
private subscriptionOptions(): SubscriptionOptions {
return this.client.subscriptionOptions()
.setOption1()
.setOption2(this.ackTimeout)
.setOption2(true)
.setDurableName(this.groupName);
}
listen(): void {
const subscription = this.client.subscribe(this.subject, this.groupName, this.subscriptionOptions())
subscription.on('message', (msg: Message) => {
console.log(`Message Received: ${this.subject}/${this.groupName}`);
const parsedData = this.parseMessage(msg);
this.onMessage(parsedData, msg);
});
}
private parseMessage(msg: Message): any {
const data = msg.getData();
return typeof data === 'string' ? JSON.parse(data) : JSON.parse(data.toString('utf-8'));
}
}
// EventType Listener
class EventCreated extends Listener {
groupName: string = 'event:created';
subject: string = 'event-service';
onMessage(data: any, msg: Message): void {
// Do something with data
console.log(`Received `, data);
msg.acknowledge();
}
}
Функциональный способ
type Listener = {
client: Client,
subject: string,
groupName: string,
ackTimeout: number
onMessage(data: string, msg: Message): void;
listen(): void;
parseMessage(msg: Message): string;
clientOptions(): ClientOptions
}
interface ListenerOptions {
subject: string,
groupName: string,
onMessage(data: any, msg: Message): void;
parseMessage(msg: Message): string
ackTimeout?: number,
}
const createListener = (client: Client, options: ListenerOptions): Listener => {
options.ackTimeout = options.ackTimeout || 5 * 1000;
return {
client,
groupName: options.groupName,
ackTimeout: options.ackTimeout,
subject: options.subject,
onMessage: options.onMessage,
listen: function () {
const subscription = this.client.subscribe(this.subject, this.groupName, this.clientOptions())
subscription.on('message', (msg: Message) => {
console.log(`Message Received: ${this.subject}/${this.groupName}`);
const parsedData = this.parseMessage(msg);
this.onMessage(parsedData, msg);
},
parseMessage: options.parseMessage || function (msg: Message): string {
const data = msg.getData();
return typeof data === 'string' ? JSON.parse(data) : JSON.parse(data.toString('utf-8'));
},
clientOptions: function (): ClientOptions {
// this.client.clientOptions to set various options as per external library
return this.client.clientOptions()
.setOption1(true)
.setOption2()
.setAckTimeout(this.ackTimeout)
.setGroup(this.groupName);
}
}
}
```
