God Object
Description
What does it look like?
- A single class or module holds too many responsibilities
- All kinds of processing are crammed into the class, causing changes or extensions to have wide-reaching impact
- Data storage, business logic, and state management are all mixed together
Why is it a problem?
- The class loses its clear purpose, resulting in unreadable and fragile code
- Difficult to test due to numerous dependencies and assumptions
- Cannot be reused or separated—a breeding ground for spaghetti code
Bad Example of the Anti-pattern
- TypeScript
- PHP
- Python
// Godクラス:責務が全部入り
class OrderManager {
private orders: string[] = [];
private userEmail: string = "";
private discountType: string = "none";
setUser(email: string) {
this.userEmail = email;
}
addOrder(productId: string) {
this.orders.push(productId);
}
applyDiscount(type: string) {
this.discountType = type;
}
calculateTotal(): number {
let basePrice = this.orders.length * 1000;
if (this.discountType === "student") {
return basePrice * 0.8;
} else if (this.discountType === "member") {
return basePrice * 0.9;
}
return basePrice;
}
confirmOrder() {
// 1. 在庫調整
console.log("在庫を減らす");
// 2. メール通知
console.log(`メールを ${this.userEmail} に送信`);
// 3. ログ出力
console.log("注文完了ログ");
}
}
<?php
class OrderManager {
private array $orders = [];
private string $userEmail = "";
private string $discountType = "none";
public function setUser(string $email): void {
$this->userEmail = $email;
}
public function addOrder(string $productId): void {
$this->orders[] = $productId;
}
public function applyDiscount(string $type): void {
$this->discountType = $type;
}
public function calculateTotal(): float {
$basePrice = count($this->orders) * 1000;
if ($this->discountType === "student") {
return $basePrice * 0.8;
} elseif ($this->discountType === "member") {
return $basePrice * 0.9;
}
return $basePrice;
}
public function confirmOrder(): void {
// 1. 在庫調整
echo "在庫を減らす\\n";
// 2. メール通知
echo "メールを {$this->userEmail} に送信\\n";
// 3. ログ出力
echo "注文完了ログ\\n";
}
}
class OrderManager:
def __init__(self):
self.orders = []
self.user_email = ""
self.discount_type = "none"
def set_user(self, email: str):
self.user_email = email
def add_order(self, product_id: str):
self.orders.append(product_id)
def apply_discount(self, discount_type: str):
self.discount_type = discount_type
def calculate_total(self) -> float:
base_price = len(self.orders) * 1000
if self.discount_type == "student":
return base_price * 0.8
elif self.discount_type == "member":
return base_price * 0.9
return base_price
def confirm_order(self):
# 1. 在庫調整
print("在庫を減らす")
# 2. メール通知
print(f"メールを {self.user_email} に送信")
# 3. ログ出力
print("注文完了ログ")
Issues
- Order data handling, discount logic, notification, and logging are all handled by a single class
- It is unclear “what this class is supposed to do”
- The class tends to grow into a monolith that is difficult to test and prone to cascading changes
Refactoring by Pattern
Design patterns that can address this
Pattern | Overview | Main Refactoring Approach |
---|---|---|
Facade | Hide internal complexity behind a unified interface | Make multiple subsystems accessible through one API |
Strategy | Make behavior interchangeable | Improve testability and extensibility |
State | Separate behavior by internal state | Replace conditionals with state-specific classes |
Composite | Organize in a tree structure for unified access | Clarify responsibilities across hierarchy |
Iterator | Abstract the way collections are traversed | Encapsulate iteration logic for better maintainability |