Last active
May 22, 2020 17:56
-
-
Save calexandrepcjr/a8fc5a976cae6b7cdc04a939232c261e to your computer and use it in GitHub Desktop.
Inspired by Michael Feathers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* UNCONDITIONAL CODE EXAMPLE - INSPIRED BY Michael Feathers | |
* | |
* https://www.youtube.com/watch?v=AnZ0uTOerUI | |
*/ | |
// OLD CODE | |
enum MessageType { | |
EXTERNAL = "external", | |
INTERNAL = "internal", | |
REPORT = "report", | |
NOTIFICATION = "notification", | |
} | |
interface Publishable<T> { | |
messageType: MessageType; | |
data: T; | |
} | |
class Queue { | |
public constructor(private readonly queue: unknown[] = []) { } | |
public add(element: unknown): void { | |
this.queue.push(element); | |
} | |
public clean(): void { | |
this.queue.length = 0; | |
} | |
public toArray(): unknown[] { | |
return this.queue; | |
} | |
} | |
abstract class BaseMessageService { | |
public constructor(public readonly queue: Queue = new Queue()) { } | |
public publish<T>(message: unknown): void { | |
this.queue.add(JSON.stringify(message)); | |
} | |
} | |
class OldMessageService extends BaseMessageService { | |
public publish<T>(message: Publishable<T>): void { | |
super.publish(this.parse(message)); | |
} | |
private parse<T>(message: Publishable<T>): unknown { | |
switch (message.messageType) { | |
case MessageType.EXTERNAL: | |
return { | |
externalData: message.data, | |
}; | |
case MessageType.INTERNAL: | |
return { | |
internalData: message.data, | |
}; | |
case MessageType.REPORT: | |
return { | |
reportData: message.data, | |
}; | |
case MessageType.NOTIFICATION: | |
return { | |
notificationData: message.data, | |
}; | |
default: | |
return message.data; | |
} | |
} | |
} | |
interface Nameable { | |
name: string; | |
} | |
abstract class OldWhisperMessage implements Publishable<Nameable> { | |
abstract readonly messageType: MessageType; | |
protected constructor(public readonly data: Nameable, nameWordQuantity: number = -1) { | |
this.data.name = this.data.name.split(" ", nameWordQuantity).join(" "); | |
} | |
} | |
class OldWhisperExternalMessage extends OldWhisperMessage { | |
public readonly messageType: MessageType = MessageType.EXTERNAL; | |
public constructor(data: Nameable) { | |
super(data, 2); | |
} | |
} | |
class OldWhisperInternalMessage extends OldWhisperMessage { | |
public readonly messageType: MessageType = MessageType.INTERNAL; | |
public constructor(data: Nameable) { | |
super(data, 1); | |
} | |
} | |
class OldWhisperReportMessage extends OldWhisperMessage { | |
public readonly messageType: MessageType = MessageType.REPORT; | |
public constructor(data: Nameable) { | |
super(data); | |
} | |
} | |
class OldWhisperNotificationMessage extends OldWhisperMessage { | |
public readonly messageType: MessageType = MessageType.NOTIFICATION; | |
public constructor(data: Nameable) { | |
super(data, 3); | |
} | |
} | |
// INSIDE A RANDOM OLD LISTENER | |
const dataReceivedByListener = () => { return { name: "Carlos Alexandre Pires de Carvalho Junior" } }; | |
const externalMessage = new OldWhisperExternalMessage(dataReceivedByListener()); | |
const internalMessage = new OldWhisperInternalMessage(dataReceivedByListener()); | |
const reportMessage = new OldWhisperReportMessage(dataReceivedByListener()); | |
const notificationMessage = new OldWhisperNotificationMessage(dataReceivedByListener()); | |
const oldQueue = new Queue(); | |
const publisher = new OldMessageService(oldQueue); | |
publisher.publish(externalMessage); | |
publisher.publish(internalMessage); | |
publisher.publish(reportMessage); | |
publisher.publish(notificationMessage); | |
console.log("QUEUE OLD STATE", oldQueue.toArray()); | |
// NEW UNCONDITIONAL CODE | |
interface Jsonable { | |
toJSON(): object; | |
} | |
abstract class WhisperMessage implements Publishable<Nameable>, Jsonable { | |
abstract readonly messageType: MessageType; | |
protected constructor(public readonly data: Nameable, nameWordQuantity: number = -1) { | |
this.data.name = this.data.name.split(" ", nameWordQuantity).join(" "); | |
} | |
public abstract toJSON(): object; | |
} | |
class WhisperExternalMessage extends WhisperMessage { | |
public readonly messageType: MessageType = MessageType.EXTERNAL; | |
public constructor(data: Nameable) { | |
super(data, 2); | |
} | |
public toJSON(): object { | |
return { | |
externalData: this.data, | |
}; | |
} | |
} | |
class WhisperInternalMessage extends WhisperMessage { | |
public readonly messageType: MessageType = MessageType.INTERNAL; | |
public constructor(data: Nameable) { | |
super(data, 1); | |
} | |
public toJSON(): object { | |
return { | |
internalData: this.data, | |
}; | |
} | |
} | |
class WhisperReportMessage extends WhisperMessage { | |
public readonly messageType: MessageType = MessageType.REPORT; | |
public constructor(data: Nameable) { | |
super(data); | |
} | |
public toJSON(): object { | |
return { | |
reportData: this.data, | |
}; | |
} | |
} | |
class WhisperNotificationMessage extends WhisperMessage { | |
public readonly messageType: MessageType = MessageType.NOTIFICATION; | |
public constructor(data: Nameable) { | |
super(data, 3); | |
} | |
public toJSON(): object { | |
return { | |
notificationData: this.data, | |
}; | |
} | |
} | |
class MessageService extends BaseMessageService { | |
public publish<T>(message: Publishable<T>): void { | |
super.publish(message); | |
} | |
} | |
// INSIDE A RANDOM OLD LISTENER | |
const newExternalMessage = new WhisperExternalMessage(dataReceivedByListener()); | |
const newInternalMessage = new WhisperInternalMessage(dataReceivedByListener()); | |
const newReportMessage = new WhisperReportMessage(dataReceivedByListener()); | |
const newNotificationMessage = new WhisperNotificationMessage(dataReceivedByListener()); | |
const newQueue = new Queue(); | |
const newPublisher = new MessageService(newQueue); | |
newPublisher.publish(newExternalMessage); | |
newPublisher.publish(newInternalMessage); | |
newPublisher.publish(newReportMessage); | |
newPublisher.publish(newNotificationMessage); | |
console.log("QUEUE NEW STATE", newQueue.toArray()); | |
/** | |
* QUEUE OLD STATE | |
(4) […] | |
| |
0: "{\"externalData\":{\"name\":\"Carlos Alexandre\"}}" | |
| |
1: "{\"internalData\":{\"name\":\"Carlos\"}}" | |
| |
2: "{\"reportData\":{\"name\":\"Carlos Alexandre Pires de Carvalho Junior\"}}" | |
| |
3: "{\"notificationData\":{\"name\":\"Carlos Alexandre Pires\"}}" | |
| |
length: 4 | |
| |
<prototype>: Array [] | |
main-3.js line 1239 > eval:106:9 | |
QUEUE NEW STATE | |
(4) […] | |
| |
0: "{\"externalData\":{\"name\":\"Carlos Alexandre\"}}" | |
| |
1: "{\"internalData\":{\"name\":\"Carlos\"}}" | |
| |
2: "{\"reportData\":{\"name\":\"Carlos Alexandre Pires de Carvalho Junior\"}}" | |
| |
3: "{\"notificationData\":{\"name\":\"Carlos Alexandre Pires\"}}" | |
| |
length: 4 | |
| |
<prototype>: Array [] | |
main-3.js line 1239 > eval:173:9 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment