はじめに
SOLID原則は様々の言語とフレームワークによく使われるデザインパターンの一つです。SOLID原則を3分の記事に分けて軽く紹介できればと思います、
SOLID原則の紹介
SOLIDとは、Robert C. Martin(通称Uncle Bob)によって考案された、オブジェクト指向プログラミングと設計の5つの基本原則を示す略語です。これらの原則は、よりクリーン、保全性、そしてフレキシブルなコードを書く基礎になると思います。それぞれの文字が何を意味するかを簡単に説明しましょう:
- S - 単一責任の原則(SRP):1つの実体(モジュール、クラス、関数、などなど)は1つのことのみ責任追跡を負うべきである
- O - オープン/クローズドの原則(OCP):ソフトウェアの実体(モジュール、クラス、関数、などなど)は拡張にはオープンでが、変更にはクローズドであるべきです
- L - リスコフの置換原則(LSP):スーパークラスのオブジェクトは、そのサブクラスのオブジェクトで置換できるべきで、プログラムの正確性に影響なしであるべき
- I - インターフェース分離の原則(ISP):コードは使用しないメソッドに強制的に依存すべきではありません
- D - 依存性逆転の原則(DIP):上位のモジュールは下位のモジュールに依存すべきではありません、両方が抽象に依存するべきです
SOLID原則はなぜ重要なのか?
コードベースが成長するに応じて、維持および拡張することはますます困難になります。開発者はフレキシブルで動的で有効的コードを書くのが目的あるべきと思います。
そこでSOLID原則を中心に開発することでこちらの重要点を守れます:
- 保守性:各原則はコードの組織化の特定の側面を提唱し、コードの理解、修正、およびデバッグを容易にします
- スケーラビリティ:SOLID原則に従うことで、コードベースが柔軟性を持ち、要件が進化するにつれてスケーラビリティが向上します
- テスト可能性:SOLID原則に従って構造化されたコードは、よりモジュール化されている傾向があり、ユニットテストが容易になり、意図しない副作用のリスクが低減します
それでは各SOLID原則について詳しく、その要点、適用可能性、実装戦略、利点、および潜在的な制限について、具体的にコード例を使用して説明していきましょう。
単一責任の原則(SRP)
単一責任とは1つのクラスが1つのことのみ責任持つべきと意味しています。よくある間違えとしてはクラスにさまざまのことを行うことです。例えばネットワークコール、関数の処理、ViewControllerへのデータの受け渡しなど1つのクラスに書くとコードがテストかなり難しくなりましと後から拡張するのも大変になります。
悪例:
class UserManager {
static let shared = UserManager()
private init() {}
func handleAllActions() {
let userData = getUsers()
let userArray = parseDataToJson(data: userData)
saveDataToDB(users: userArray)
}
func getUsers() -> Data {
// APIリクエストを送信し、応答を待つ
}
func parseDataToJson(data: Data) -> [String] {
// データを解析して配列に変換する
}
func saveDataToDB(users: [String]) {
// 配列をCoreDataに保存する
}
}
好例:
class UserManager {
var userAPIHandler: UserAPIHandler?
var parseDataHandler: ParseDataHandler?
var saveDataToDBHandler: SaveDataToDBHandler?
init(userAPIHandler: UserAPIHandler, parseDataHandler: ParseDataHandler, saveDataToDBHandler: SaveDataToDBHandler) {
self.userAPIHandler = userAPIHandler
self.parseDataHandler = parseDataHandler
self.saveDataToDBHandler = saveDataToDBHandler
}
func handleAllActions() {
guard let userAPIHandler else { return }
guard let parseDataHandler else { return }
guard let saveDataToDBHandler else { return }
let userData = userAPIHandler.getUsers()
let userArray = parseDataHandler.parseDataToJson(data: userData)
saveDataToDBHandler.saveDataToDB(users: userArray)
}
}
class UserAPIHandler {
func getUsers() -> Data {
// APIリクエストを送信し、応答を待つ
}
}
class ParseDataHandler {
func parseDataToJson(data: Data) -> [String] {
// データを解析して配列に変換する
}
}
class SaveDataToDBHandler {
func saveDataToDB(users: [String]) {
// 配列をCoreDataに保存する
}
}
好例では各クラスが単一の明確な責任を持ち、複数のタスクをこなしていないことでコードがテストしやすいし、拡張することも簡単でできることです。
異なる責任を特定し、それらを別々のクラスや関数に密閉化することがSRPを使用することです。SRPはクラスだけじゃなくてメソッド、およびモジュールにも適用されます。コードの部門が向上し、保守性とテストが容易となります。
注意すること制限は過度な分離が複雑さとパフォーマンスのオーバーヘッドを引き起こす可能性が高まります。
結論
いくつのルールを守って簡単にSolid原則使用してコードベースの保守性を向上させることができます。続いてSolid原則の理解高めて良いコードベース作る開発者を目指しましょう。
次の記事まで、ハッピーコーディング!