LoginSignup
123
114

More than 5 years have passed since last update.

[Swift版]クリーンアーキテクチャ実践編①(Domain層)

Last updated at Posted at 2016-07-24

はじめに

最近巷で、熱い『クリーンアーキテクチャ』を社内案件でも導入しています。
まだまだ不完全な部分も多いので、今一度整理してみました。

今回はDomain層を中心に纏めてみました。

やること

  • UI層

    • View
    • ViewController
    • Presenter
  • Domain層

    • Usecase ← ここ説明します
    • Repository ← ここ説明します
    • Entity ← ここ説明します
  • Data層

    • Repository ← ここ説明します
    • Entity
    • DataStore

やらないこと

・クリーンアーキテクチャーの概念について
・UI層について
・Data層について(Repositoryを除く)

ご説明する例

Usecaseからユーザ情報にアクセスする際の事例

レイヤ カテゴリ クラス名 説明
Domain層 Entity User ユーザ情報を管理するクラス(メールアドレス、誕生日)
Repository UserRepository ユーザ情報とのインターフェース
Usecase UserUsecase 業務ロジッククラス
Data層 Repository UserRepositoryImpl ユーザ情報へアクセスする実体のクラス

1. Domain層のEntityについて

ユーザ情報として、メールアドレスと誕生日を保持するクラス

User.swift
import Foundation

class User: NSObject {
    var mailAddress = ""
    var birthDay  = ""
}

2. Domain層のRepositoryについて

ユーザ情報へアクセスする手段を纏めたインターフェース(プロトコル)
DAOに近いイメージ???
利用する側は、どこに保存されているかは意識しない。

UserRepository.swift
import Foundation

protocol UserRepository: class {
    func store(user: User)
    func user(userID: NSInteger) -> User
    func users() -> [User]
    func delete(userID: NSInteger)
}

3. Data層のRepositoryについて

UserRepositoryプロトコルを実装したクラス

ユーザ情報の保存先は、仕様に合わせて、アプリ内でも、サーバーサイドでも良い。

UserRepositoryImpl.swift
class UserRepositoryImpl: UserRepository {

    func store(user: User) {
        //TODO: ユーザ情報をどこかに保存する
    }

    func user(userID: NSInteger) -> User {

        //TODO: ユーザ情報をどこかから取得する
        return User()
    }

    func users() -> [User] {

        //TODO: ユーザ情報をどこかから取得する
         return []
    }

    func delete(userID: NSInteger) {
        //TODO: どこかに保存しているユーザ情報を削除する
    }
}

4. Domain層のUsecaseについて

UserUsecase.swift
import Foundation

class UserUsecase: NSObject {

    let repository: UserRepository

    init(repository: UserRepository) {
        self.repository = repository
        super.init()
    }

    //メールアドレスを保存する
    func storeMailAddressByID(userID: NSInteger, mailAddress: String) {

        let user = repository.user(userID)
        user.mailAddress = mailAddress
        repository.store(user)
    }

    //メールアドレスを取得する
    func findMailAddressByID(userID: NSInteger) -> String {
        return repository.user(userID).mailAddress
    }

    //誕生日を保存する
    func storeBirthDayByID(userID: NSInteger, birthDaty: String) {

        let user = repository.user(userID)
        user.birthDay = birthDaty
        repository.store(user)
    }

    //誕生日を取得する
    func findBirthDayByID(userID: NSInteger) -> String {
        return repository.user(userID).birthDay
    }
}

まとめ

ポイントは、Domain層のRepositoryだと思います。

  1. データにアクセスするためには、Domain層のRepositoryを通してアクセスする。

  2. データにアクセスするクライアントは、保存先がサーバー(API経由)なのかアプリ内(CoreData、UserDefaultsなど)か意識しない。

誤りやもっとこうしたほうが良いとというアドバイスがございましたら、ご指摘頂けますと幸いです。

こちらも合わせて読んで頂ければ幸いです。
[Swift版]クリーンアーキテクチャ実践編②(Data層)

謝辞

@KentaKudoさん、ご指摘ありがとうございます。
依存性の注入(Dependency Injection)の観点で、
柔軟性がない、テストしにくいため、
UserUsecaseを修正しました。

123
114
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
123
114