Scattered Concerns
Description
What does it look like?
- Logging logic and configuration access are written inconsistently across the codebase
- Each part of the system logs messages or loads config values in its own way, lacking consistency
- Implementation of logs and configs tends to vary depending on the developer
Why is it a problem?
- Low maintainability and poor reusability
- When log format or destination needs to change, the impact is widespread
- Incorrect config access or repeated loading may lead to performance issues and bugs
Bad Example of the Anti-pattern
- TypeScript
- PHP
- Python
// あちこちで Logger や設定を直接扱っている
class OrderService {
createOrder(orderId: string) {
console.log(`[OrderService] 注文作成: ${orderId}`); // 直書きログ
const debugMode = process.env.DEBUG_MODE === "true"; // 設定の直接参照
if (debugMode) {
console.log(`[DEBUG] 注文詳細: ${orderId}`);
}
}
}
class UserService {
createUser(name: string) {
console.log(`[UserService] ユーザー作成: ${name}`);
}
}
<?php
class OrderService {
public function createOrder(string $orderId): void {
echo "[OrderService] 注文作成: {$orderId}\n"; // 直書きログ
$debugMode = getenv("DEBUG_MODE") === "true"; // 設定の直接参照
if ($debugMode) {
echo "[DEBUG] 注文詳細: {$orderId}\n";
}
}
}
class UserService {
public function createUser(string $name): void {
echo "[UserService] ユーザー作成: {$name}\n"; // 直書きログ
}
}
// 環境変数設定(実行前に CLI などで設定)
// putenv("DEBUG_MODE=true");
$orderService = new OrderService();
$orderService->createOrder("order-123");
$userService = new UserService();
$userService->createUser("hiroshi");
import os
class OrderService:
def create_order(self, order_id: str):
print(f"[OrderService] 注文作成: {order_id}") # 直書きログ
debug_mode = os.environ.get("DEBUG_MODE") == "true" # 設定の直接参照
if debug_mode:
print(f"[DEBUG] 注文詳細: {order_id}")
class UserService:
def create_user(self, name: str):
print(f"[UserService] ユーザー作成: {name}") # 直書きログ
# 実行例
# os.environ["DEBUG_MODE"] = "true"
order_service = OrderService()
order_service.create_order("order-123")
user_service = UserService()
user_service.create_user("hiroshi")
Issues:
- Direct use of
console.log()
→ Must update every log when the format changes - Direct access to
process.env
→ No centralized configuration management - Responsibility is scattered and reuse is difficult
Refactoring by Pattern
Design patterns that can address this
Pattern | Overview | Main Refactoring Approach |
---|---|---|
Singleton | Restrict instance to one across the application | Manage logs and configs as shared state |
Facade | Provide a simplified API for logging and config access | Create a unified interface for use |