Problem: Compress Files with Switchable Encoders

Medium
30 min
Build a compression utility that can switch between different algorithms—Gzip, Brotli, and none—without modifying the main compression logic.

Problem statement

Your app processes large log files before uploading them to cloud storage. Different environments require different compression types:

  • Development uses no compression for easy debugging.

  • Staging uses Gzip for quick compression.

  • Production uses Brotli for maximum space savings.

Compression systems often hardcode algorithm selection with if statements, making them fragile as new rules are added or modified. Each change risks breaking existing behavior. Design a file compression utility using the Strategy Pattern so that each compression algorithm is encapsulated, ensuring a consistent file-processing workflow.

Goal

Implement both pieces of the pattern:

  1. Encoders (Strategies):

    1. GzipEncoder: Simulate compression with a delay and return "gzipped:<data>".

    2. BrotliEncoder: Simulate compression with a longer delay and return "brotli:<data>".

    3. NoCompression: Return the original data immediately.

    4. Each must define an async .compress(data) method.

  2. Compressor (Context):

    1. Implements .compress(data) that delegates to the current encoder’s method.

    2. Must support runtime switching through .setEncoder().

Constraints

  • The .compress() methods must return a Promise.

  • Compressor must not use if or switch logic to select encoders.

  • Simulate async behavior using setTimeout inside Promises.

  • The output should clearly reflect which encoder was used.

Sample output

The examples below illustrate what the output should look like:

(async () => {
const compressor = new Compressor(new GzipEncoder());
console.log(await compressor.compress('log data'));
/* Expected output:
gzipped:log data
*/
compressor.setEncoder(new BrotliEncoder());
console.log(await compressor.compress('log data'));
/* Expected output:
brotli:log data
*/
compressor.setEncoder(new NoCompression());
console.log(await compressor.compress('log data'));
/* Expected output:
log data
*/
})();

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Problem: Compress Files with Switchable Encoders

Medium
30 min
Build a compression utility that can switch between different algorithms—Gzip, Brotli, and none—without modifying the main compression logic.

Problem statement

Your app processes large log files before uploading them to cloud storage. Different environments require different compression types:

  • Development uses no compression for easy debugging.

  • Staging uses Gzip for quick compression.

  • Production uses Brotli for maximum space savings.

Compression systems often hardcode algorithm selection with if statements, making them fragile as new rules are added or modified. Each change risks breaking existing behavior. Design a file compression utility using the Strategy Pattern so that each compression algorithm is encapsulated, ensuring a consistent file-processing workflow.

Goal

Implement both pieces of the pattern:

  1. Encoders (Strategies):

    1. GzipEncoder: Simulate compression with a delay and return "gzipped:<data>".

    2. BrotliEncoder: Simulate compression with a longer delay and return "brotli:<data>".

    3. NoCompression: Return the original data immediately.

    4. Each must define an async .compress(data) method.

  2. Compressor (Context):

    1. Implements .compress(data) that delegates to the current encoder’s method.

    2. Must support runtime switching through .setEncoder().

Constraints

  • The .compress() methods must return a Promise.

  • Compressor must not use if or switch logic to select encoders.

  • Simulate async behavior using setTimeout inside Promises.

  • The output should clearly reflect which encoder was used.

Sample output

The examples below illustrate what the output should look like:

(async () => {
const compressor = new Compressor(new GzipEncoder());
console.log(await compressor.compress('log data'));
/* Expected output:
gzipped:log data
*/
compressor.setEncoder(new BrotliEncoder());
console.log(await compressor.compress('log data'));
/* Expected output:
brotli:log data
*/
compressor.setEncoder(new NoCompression());
console.log(await compressor.compress('log data'));
/* Expected output:
log data
*/
})();

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Node.js
// --- Strategies (implement these) ---
class GzipEncoder {}
class BrotliEncoder {}
class NoCompression {}
// --- Context (implement this too) ---
class Compressor {
constructor(encoder) {}
setEncoder(encoder) {}
async compress(data) {}
}
// Example usage
(async () => {
const compressor = new Compressor(new GzipEncoder());
console.log(await compressor.compress('log data'));
/* Expected output:
gzipped:log data
*/
compressor.setEncoder(new BrotliEncoder());
console.log(await compressor.compress('log data'));
/* Expected output:
brotli:log data
*/
compressor.setEncoder(new NoCompression());
console.log(await compressor.compress('log data'));
/* Expected output:
log data
*/
})();