Refactoring Task
Overview
This exercise focuses on identifying design issues caused by the "God Object" anti-pattern, where a single class accumulates multiple responsibilities.
The goal is to analyze the problems and propose refactoring strategies using appropriate design patterns to improve the structure.
Initial Code
The following code shows the implementation of a PostManager
class that handles all logic related to blog posts.
Analyze this code for structural problems and consider ways to improve it.
- TypeScript
- PHP
- Python
// PostManager クラスが責務過多
class PostManager {
private posts: { title: string; content: string }[] = [];
private authorEmail: string = "";
setAuthor(email: string) {
this.authorEmail = email;
}
createPost(title: string, content: string) {
this.posts.push({ title, content });
}
publishAll() {
for (const post of this.posts) {
// 1. データベース保存(仮)
console.log(`保存: ${post.title}`);
// 2. 通知送信
console.log(`通知を ${this.authorEmail} に送信`);
// 3. ログ出力
console.log(`ログ: ${post.title} を公開`);
}
}
}
<?php
class PostManager {
private array $posts = [];
private string $authorEmail = "";
public function setAuthor(string $email): void {
$this->authorEmail = $email;
}
public function createPost(string $title, string $content): void {
$this->posts[] = ['title' => $title, 'content' => $content];
}
public function publishAll(): void {
foreach ($this->posts as $post) {
// 1. データ保存
echo "保存: {$post['title']}\n";
// 2. 通知送信
echo "通知を {$this->authorEmail} に送信\n";
// 3. ログ
echo "ログ: {$post['title']} を公開\n";
}
}
}
class PostManager:
def __init__(self):
self.posts = []
self.author_email = ""
def set_author(self, email: str):
self.author_email = email
def create_post(self, title: str, content: str):
self.posts.append({"title": title, "content": content})
def publish_all(self):
for post in self.posts:
# 1. データ保存
print(f"保存: {post['title']}")
# 2. 通知送信
print(f"通知を {self.author_email} に送信")
# 3. ログ出力
print(f"ログ: {post['title']} を公開")
Question 1: What are the design issues in this code?
List concrete issues by considering the following perspectives:
- Lack of responsibility separation (Are multiple concerns mixed within a single class?)
- Poor extensibility and maintainability (Is the code prone to ripple effects when modified?)
- Lack of reusability (Are parts of the code difficult to reuse elsewhere?)
- Low testability (Can each functionality be tested in isolation?)
Question 2: How would you refactor this class?
Discuss your ideas with the following elements in mind:
- Concerns that should be separated (e.g., posting logic, notification handling, logging)
- Benefits of splitting responsibilities into separate classes or services
- Design patterns applicable to each concern and their intended purpose/effect
Example: Candidate Patterns
Pattern | Primary Purpose and Benefit |
---|---|
Facade | Consolidates post-confirmation logic into a single interface, simplifying the caller |
Strategy | Makes the notification method (e.g., Email / Slack) easily swappable |
State | Enables behavior to vary based on post state (e.g., draft / published) |
Composite | Structures posts so they can be handled as a group (e.g., batch publishing) |
Iterator | Enables safe and abstracted iteration through post collections |
Optional Extensions
For the following feature additions, consider what design strategies would be appropriate:
- Introduce state management for posts (e.g., "scheduled", "published")
- Allow notification channels (Slack, LINE, email) to be configurable externally
- Enable custom templates per post
Suggested Output Format (for team review or study groups)
- Structural issues identified (at least 3 items)
- Refactoring strategy and justification
- Proposed design patterns and rationale for selection
- (Optional) Diagram of improved class structure