はじめに
ソフトウェア開発において「設計原則(Design Principles)」は、保守性・拡張性・可読性 を高めるための基本的な考え方です。
この記事では、代表的な SOLID原則 を中心に、補助的な設計指針、UI/UX設計原則、アーキテクチャ設計原則までを整理します。
1. SOLID原則(オブジェクト指向設計の基本)
SRP:単一責任の原則(Single Responsibility Principle)
クラスやモジュールは「変更理由が一つだけ」であるべき
例(Kotlin)
// ❌ NG: ネットワーク通信とDB保存を1クラスにまとめている
class UserRepository {
fun fetchUserFromApi() { /* ... */ }
fun saveUserToDb() { /* ... */ }
}
// ✅ OK: 責務ごとに分離する
interface ApiDataSource {
fun fetchUser(): User
}
interface LocalDataSource {
fun saveUser(user: User)
}
OCP:開放/閉鎖の原則(Open/Closed Principle)
拡張に対して開かれ、修正に対して閉じているべき
// 新しい戦略を追加しても既存コードを修正しない
interface DiscountPolicy {
fun apply(price: Int): Int
}
class PercentageDiscount : DiscountPolicy {
override fun apply(price: Int) = (price * 0.9).toInt()
}
class SeasonalDiscount : DiscountPolicy {
override fun apply(price: Int) = (price - 100)
}
LSP:リスコフの置換原則(Liskov Substitution Principle)
派生クラスは基底クラスとして置き換え可能であるべき
open class Bird {
open fun fly() = println("Flying...")
}
class Sparrow : Bird()
class Penguin : Bird() {
// ❌ NG: Penguinは飛べない → LSP違反
override fun fly() = throw UnsupportedOperationException()
}
ISP:インターフェース分離の原則(Interface Segregation Principle)
利用しないメソッドを強制しない
// NG: 不要なメソッドを実装させてしまう
interface Worker {
fun work()
fun eat()
}
// OK: インターフェースを分割
interface Workable { fun work() }
interface Eatable { fun eat() }
DIP:依存関係逆転の原則(Dependency Inversion Principle)
高水準モジュールは低水準に依存せず、抽象に依存する
// 高水準コードは抽象に依存
class UserService(private val repository: UserRepository)
interface UserRepository {
fun getUser(): User
}
// 具体実装は差し替え可能
class ApiUserRepository : UserRepository { /* ... */ }
class LocalUserRepository : UserRepository { /* ... */ }
2. 補助的な設計指針
-
DRY(Don’t Repeat Yourself)
→ 重複を避ける -
KISS(Keep It Simple, Stupid)
→ シンプルに保つ -
YAGNI(You Ain’t Gonna Need It)
→ 未来の不要機能を先回り実装しない -
関心の分離(Separation of Concerns)
→ 層ごとに責務を分ける -
デメテルの法則(Law of Demeter)
→ 「友達とだけ話す」=内部に深入りしすぎない
3. UI/UX設計原則
- 一貫性:UIパターンを統一
- アフォーダンスとフィードバック:操作と応答を明確化
- 階層性と明確さ:文字サイズ・余白・色で優先度を表現
- アクセシビリティ:誰でも利用可能に設計
- ミニマリズム:情報を必要最低限に
4. アーキテクチャ設計原則
- モジュール性:独立・交換可能な構造
- スケーラビリティ:利用者や機能の増加に対応
- テスタビリティ:単体テストが容易
- セキュリティ by Design:初期から安全性を考慮
- 保守性:拡張や修正のしやすさ
まとめ
- SOLID原則 はコードレベルの設計の柱
- DRY/KISS/YAGNI などの指針は日々の実装の助け
- UI/UX原則 はユーザー視点の品質向上
- アーキテクチャ原則 は長期的なシステムの健全性を守る
これらを意識することで、Clean Architecture の実践につながります。