Refactoring Task
Overview
In this task, you'll analyze a codebase where multiple classes (ApiClient
, BatchJob
) independently perform logging and configuration loading.
The goal is to identify issues such as scattered and duplicated logic, wide change impact, and to explore directions for refactoring toward better maintainability and extensibility.
Initial Code
The following example shows an API client and a batch job class, both directly using console.log
and getenv
.
There is no unified logging format or centralized configuration management, leading to problems in reusability and maintainability.
- TypeScript
- PHP
- Python
class ApiClient {
fetchData(endpoint: string) {
const apiKey = process.env.API_KEY;
console.log(`[ApiClient] APIキー: ${apiKey}`);
console.log(`[ApiClient] エンドポイントにアクセス: ${endpoint}`);
}
}
class BatchJob {
run() {
const runMode = process.env.MODE;
console.log(`[BatchJob] 実行モード: ${runMode}`);
console.log(`[BatchJob] バッチ処理開始`);
}
}
<?php
class ApiClient {
public function fetchData(string $endpoint): void {
$apiKey = getenv("API_KEY");
echo "[ApiClient] APIキー: {$apiKey}\n";
echo "[ApiClient] エンドポイントにアクセス: {$endpoint}\n";
}
}
class BatchJob {
public function run(): void {
$runMode = getenv("MODE");
echo "[BatchJob] 実行モード: {$runMode}\n";
echo "[BatchJob] バッチ処理開始\n";
}
}
import os
class ApiClient:
def fetch_data(self, endpoint: str):
api_key = os.getenv("API_KEY")
print(f"[ApiClient] APIキー: {api_key}")
print(f"[ApiClient] エンドポイントにアクセス: {endpoint}")
class BatchJob:
def run(self):
run_mode = os.getenv("MODE")
print(f"[BatchJob] 実行モード: {run_mode}")
print("[BatchJob] バッチ処理開始")
Question 1: What are the design issues in this code?
List and describe structural problems, considering the following points:
- Duplicate logging logic scattered across multiple classes
- Responsibility for configuration loading is fragmented
- No consistent logging format or log levels, making future changes difficult
- No abstraction for infrastructure concerns such as logging and configuration
Question 2: How can this structure be improved for better maintainability and extensibility?
Organize your refactoring plan based on the following points:
- How to standardize and centralize logging and its format
- How to decouple configuration access from individual classes
- How to design a shared infrastructure layer reusable across the entire application
Example: Candidate Design Patterns
Pattern Name | Purpose and Effect |
---|---|
Singleton | Centralize logging and configuration logic into a single globally shared instance |
Facade | Provide a simplified API for complex logging/configuration logic |
Adapter | Wrap external logging/config libraries with app-specific interfaces |
Service Locator | Centralize access to common services, eliminating the need for manual instantiation |
Optional Extensions
- If you need to switch log output destinations (console, file, database), how should the design evolve?
- If configuration values are loaded from DB or external APIs instead of
.env
, what impact will that have and how should it be handled?
Suggested Output Format (for review or team discussion)
- List of structural problems (at least 3)
- Refactoring strategy and justification for selected patterns
- Overview of the improved architecture (e.g., how logging/config/business logic responsibilities are separated)