Skip to main content

Refactoring Task

Overview​

In this exercise, you will analyze a Notifier class implementation in which an external dependency (Mailer) is instantiated with new each time it is needed.
Identify the design issues this introduces, and propose refactoring strategies that improve flexibility and testability.

Initial Code​

The following code defines a Notifier class responsible for sending notifications to users.
It directly instantiates the Mailer internally, which works initially, but could lead to maintainability and extensibility problems over time.

class Mailer {
send(to: string, message: string) {
console.log(`パール送俑: ${to} => ${message}`);
}
}

class Notifier {
notify(userId: string, content: string) {
const mailer = new Mailer();
const formatted = `[ι€šηŸ₯] ${content}`;
mailer.send(`${userId}@example.com`, formatted);
}
}

Question 1: What are the design issues in this code?​

List and explain the design problems based on the following aspects:

  • Testability (Is it possible to replace Mailer for testing?)
  • Flexibility (What if the type of mailer needs to be changed?)
  • Dependency management (Is Notifier too tightly coupled to Mailer?)
  • Conformance to design principles (e.g., the Dependency Inversion Principle)

Question 2: How should the design be improved?​

Propose improvements based on the following considerations:

  • How can Notifier be decoupled from the internal instantiation of Mailer?
  • How can the Mailer be replaced during unit testing?
  • What benefits arise from applying Dependency Injection?

Example: Design Pattern Candidates​

Pattern NamePurpose and Effects
Factory MethodExtracts object creation logic and allows switching implementations as needed
Abstract FactoryProvides a group of related objects (e.g., Mailer, Logger) as a unified interface
BuilderSeparates construction steps and enables flexible, step-by-step initialization
SingletonEnsures only one instance exists globally and is reused across the system
Dependency InjectionInjects dependencies externally for better flexibility, testability, and decoupling

Optional Extensions​

  • If notification methods include Slack or LINE in addition to email, how would you adapt the design?
  • If the test environment requires a mock mailer that logs instead of sending, how would you design for this flexibility?

Suggested Output Format (for review or study groups)​

  • List of at least three structural problems
  • Refactoring approach and the reason for choosing specific patterns
  • Design rationale and improvements (with optional sketches or pseudocode)