Facade Design Pattern
The Facade Pattern provides a simplified interface to a complex software system by hiding its underlying components. It helps to reduce dependencies and improves usability.
We will discuss the benefits of this pattern by introducing a Typescript example for Encryption algorithm. We call this class as the EncryptionFacade.
The facade introduces a single-entry point to the system, hiding the complexity of multiple systems. The EncryptionFacade class provides two methods encryptData() and decryptData() instead of exposing multiple encryption classes.
The facade pattern provides loose coupling thereby decoupling the client from the system. This helps the user to avoid the complex cryptographic algorithms. The encryption logic centralised reducing duplication and making future updates easier. If encryption logic changes, only EncryptionFacade needs modification, not every client that uses encryption.
import * as crypto from 'crypto';
import { AESEncryption } from './AESEncryption';
// FACADE: Simplifies Encryption & Decryption
class EncryptionFacade {
private encryptionService = new AESEncryption();
encryptData(data: string): string {
return this.encryptionService.encrypt(data);
}
decryptData(encryptedData: string): string {
return this.encryptionService.decrypt(encryptedData);
}
}
function main() {
const facade = new EncryptionFacade();
const encryptedText = facade.encryptData("Confidential Data");
console.log("Encrypted:", encryptedText);
const decryptedText = facade.decryptData(encryptedText);
console.log("Decrypted:", decryptedText);
}
main();
The code snippet provides the details for the facade class. The user interacts using the two methods encryptData() and decryptData() without having to know the intricate details.
The actual AES encryption class is as below:
import * as crypto from 'crypto';
export class AESEncryption {
private key = crypto.createHash('sha256').update('my-secured-key').digest();
private generateIV(): Buffer {
return crypto.randomBytes(16);
}
encrypt(data: string): string {
const iv = this.generateIV();
const cipher = crypto.createCipheriv('aes-256-cbc', this.key, iv);
let encrypted = cipher.update(data, 'utf-8', 'hex');
encrypted += cipher.final('hex');
return `${iv.toString('hex')}:${encrypted}`; // Store IV with encrypted data
}
decrypt(encryptedData: string): string {
const [ivHex, encrypted] = encryptedData.split(':');
const iv = Buffer.from(ivHex, 'hex');
const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf-8');
decrypted += decipher.final('utf-8');
return decrypted;
}
}
The GITHUB link for the code is available HERE.
For the readers who are curious to know about the AES algorithm details, they can read the comments here.