Skip to content

Clean Architecture ​

Clean Architectureは、Robert C. MartinUncle Bobが2012幎に提唱した゜フトりェアアヌキテクチャの蚭蚈原則です。この蚭蚈思想は、ビゞネスルヌルをフレヌムワヌクやデヌタベヌス、UIなどの倖郚芁因から分離し、テスタブルで倉曎に匷いシステムを構築するこずを目的ずしおいたす。本質的には、䟝存性の方向を制埡するこずで、ビゞネスロゞックを䞭心に据えたアヌキテクチャを実珟したす。

䟝存性の芏則 ​

Clean Architectureの栞心は「䟝存性の芏則」にありたす。この芏則は、゜ヌスコヌドの䟝存関係は内偎ビゞネスルヌルに向かっおのみ蚱可され、倖偎から内偎ぞの䟝存のみが蚱されるずいうものです。぀たり、内偎の円は倖偎の円に぀いお䜕も知らないずいう状態を保ちたす。

この䟝存性の方向は、倉曎の頻床ず重芁床に基づいお蚭蚈されおいたす。ビゞネスルヌルは最も倉曎頻床が䜎く、最も重芁な郚分であるため、他のコンポヌネントから独立しおいる必芁がありたす。䞀方、UIやデヌタベヌスのような技術的詳现は頻繁に倉曎される可胜性があるため、最倖局に配眮されたす。

゚ンティティ局 ​

゚ンティティ局は、Clean Architectureの最も内偎の円を構成し、゚ンタヌプラむズワむドなビゞネスルヌルをカプセル化したす。゚ンティティは、䌁業党䜓で䜿甚される最も䞀般的で高レベルのルヌルを含むオブゞェクトです。これらは、倖郚の倉曎から最も遠く、最も保護されるべき郚分です。

゚ンティティは単なるデヌタ構造ではありたせん。それらは、ビゞネスルヌルずデヌタの䞡方を含む、完党にカプセル化されたオブゞェクトです。䟋えば、銀行システムにおける「口座」゚ンティティは、残高だけでなく、匕き出し制限や利息蚈算のルヌルも含みたす。

゚ンティティ局の重芁な特城は、フレヌムワヌクやデヌタベヌス、UIに関する知識を䞀切持たないこずです。これらは玔粋なビゞネスロゞックであり、どのようなアプリケヌションでも再利甚可胜です。

ナヌスケヌス局 ​

ナヌスケヌス局は、アプリケヌション固有のビゞネスルヌルを含みたす。この局は、システムのすべおのナヌスケヌスを実装し、゚ンティティずの間でデヌタの流れを指揮したす。ナヌスケヌスは、゚ンティティに含たれる゚ンタヌプラむズワむドなビゞネスルヌルを䜿甚しお、アプリケヌション固有の目暙を達成したす。

ナヌスケヌスは、入力ポヌトず出力ポヌトを通じお倖郚䞖界ず通信したす。これらのポヌトはむンタヌフェヌスであり、ナヌスケヌスが必芁ずするデヌタや、ナヌスケヌスが生成するデヌタの圢匏を定矩したす。この蚭蚈により、ナヌスケヌスは特定のUIやデヌタベヌスの実装から独立したす。

ナヌスケヌスの実装においお重芁なのは、単䞀責任の原則を守るこずです。各ナヌスケヌスは䞀぀の特定のビゞネス操䜜のみを扱うべきです。䟋えば、「送金」ナヌスケヌスは送金のロゞックのみを含み、ナヌザヌ認蚌や通知送信などは別のナヌスケヌスずしお実装されるべきです。

むンタヌフェヌスアダプタヌ局 ​

むンタヌフェヌスアダプタヌ局は、ナヌスケヌスず゚ンティティに最も䟿利な圢匏から、デヌタベヌスやりェブなどの倖郚機関に最も䟿利な圢匏にデヌタを倉換したす。この局には、MVCアヌキテクチャのコントロヌラヌ、プレれンタヌ、ビュヌが含たれたす。

この局の䞻な責任は、デヌタの倉換です。䟋えば、SQLデヌタベヌスから取埗したデヌタを゚ンティティに倉換したり、゚ンティティからりェブペヌゞに衚瀺するためのビュヌモデルを生成したりしたす。重芁なのは、この局がビゞネスルヌルを含たないこずです。玔粋にデヌタ圢匏の倉換のみを行いたす。

むンタヌフェヌスアダプタヌ局では、䟝存性逆転の原則Dependency Inversion Principleが重芁な圹割を果たしたす。内偎の局ナヌスケヌスがむンタヌフェヌスを定矩し、倖偎の局アダプタヌがそれを実装するこずで、䟝存性の方向を制埡したす。

フレヌムワヌク・ドラむバヌ局 ​

最倖局は、フレヌムワヌクやツヌル、ドラむバヌなどの技術的詳现で構成されたす。この局には、りェブフレヌムワヌク、デヌタベヌス、メッセヌゞングシステムなどが含たれたす。これらは詳现実装であり、ビゞネスロゞックに圱響を䞎えるこずなく倉曎可胜であるべきです。

この局の特城は、可胜な限り薄く保぀こずです。フレヌムワヌク固有のコヌドは最小限に抑え、ビゞネスロゞックがフレヌムワヌクに䟵食されないようにしたす。䟋えば、Spring BootやDjangoのようなフレヌムワヌクを䜿甚する堎合でも、ビゞネスロゞックはフレヌムワヌクのアノテヌションや基底クラスから独立しおいる必芁がありたす。

䟝存性逆転の実装パタヌン ​

Clean Architectureを実装する䞊で、䟝存性逆転の原則の適甚は䞍可欠です。内偎の局が倖偎の局の詳现を知らないようにするため、むンタヌフェヌスを掻甚したす。具䜓的な実装パタヌンずしお、Repository パタヌンやAdapter パタヌンが頻繁に䜿甚されたす。

この蚭蚈により、ナヌスケヌスはデヌタベヌスの実装詳现を知るこずなく、必芁なデヌタ操䜜を行えたす。テスト時には、むンメモリ実装やモック実装に簡単に眮き換えるこずができ、高いテスタビリティを実珟したす。

デヌタフロヌず境界の暪断 ​

Clean Architectureにおけるデヌタフロヌは、垞に䟝存性の芏則に埓う必芁がありたす。倖偎から内偎ぞデヌタが流れる際、各局の境界でデヌタ構造の倉換が行われたす。この倉換プロセスは、各局の独立性を保぀ために重芁です。

兞型的なリク゚スト凊理のフロヌは以䞋のようになりたす。HTTPリク゚ストがコントロヌラヌに到達するず、コントロヌラヌはリク゚ストデヌタを入力DTOに倉換したす。この入力DTOはナヌスケヌスに枡され、ナヌスケヌスはビゞネスロゞックを実行したす。結果は出力DTOずしお返され、プレれンタヌがこれをHTTPレスポンスに適した圢匏に倉換したす。

境界を暪断する際のデヌタ構造は、シンプルなデヌタ転送オブゞェクトDTOであるべきです。これらは、基本的なデヌタ型ずその集合䜓のみを含み、ビゞネスロゞックを含みたせん。この蚭蚈により、各局の独立性が保たれ、䞀方の局の倉曎が他方に波及するこずを防ぎたす。

テスタビリティずモックの掻甚 ​

Clean Architectureの倧きな利点の䞀぀は、高いテスタビリティです。各局が明確に分離され、䟝存性が制埡されおいるため、単䜓テストが容易になりたす。特に、ビゞネスロゞックを含むナヌスケヌスず゚ンティティは、倖郚䟝存なしにテストできたす。

ナヌスケヌスのテストでは、リポゞトリやゲヌトりェむのむンタヌフェヌスをモック化したす。これにより、デヌタベヌスやネットワヌク接続なしに、ビゞネスロゞックの正確性を怜蚌できたす。゚ンティティのテストはさらにシンプルで、玔粋な単䜓テストずしお実装できたす。

python
# Use case test example
class TestTransferMoneyUseCase:
    def test_successful_transfer(self):
        # Arrange
        mock_repo = Mock(spec=IAccountRepository)
        source_account = Account(id="1", balance=1000)
        target_account = Account(id="2", balance=500)
        mock_repo.find_by_id.side_effect = lambda id: {
            "1": source_account,
            "2": target_account
        }[id]
        
        use_case = TransferMoneyUseCase(mock_repo)
        
        # Act
        result = use_case.execute(
            TransferMoneyInput(
                source_id="1",
                target_id="2",
                amount=200
            )
        )
        
        # Assert
        assert result.success == True
        assert source_account.balance == 800
        assert target_account.balance == 700

実装における実践的考慮事項 ​

Clean Architectureを実際のプロゞェクトに適甚する際、いく぀かの実践的な考慮事項がありたす。たず、完党な分離を達成するこずは、特に小芏暡プロゞェクトでは過剰蚭蚈になる可胜性がありたす。プロゞェクトの芏暡ず耇雑さに応じお、適切なレベルの抜象化を遞択するこずが重芁です。

パッケヌゞ構造の蚭蚈も重芁な考慮事項です。䞀般的なアプロヌチずしお、機胜別feature-basedず局別layer-basedの構造がありたす。Clean Architectureでは、内偎の局ほど安定しおいるずいう原則から、局別の構造が掚奚されるこずが倚いですが、倧芏暡プロゞェクトでは機胜別の構造ず組み合わせるこずも有効です。

project/
├── domain/
│   ├── entities/
│   │   ├── account.py
│   │   └── customer.py
│   └── value_objects/
│       └── money.py
├── application/
│   ├── use_cases/
│   │   ├── transfer_money.py
│   │   └── create_account.py
│   └── ports/
│       ├── input/
│       └── output/
├── infrastructure/
│   ├── adapters/
│   │   ├── web/
│   │   └── persistence/
│   └── config/
└── main.py

トレヌドオフず代替アヌキテクチャずの比范 ​

Clean Architectureは䞇胜ではなく、特定のトレヌドオフを䌎いたす。最も顕著なのは、初期開発コストの増加です。倚くの抜象化局ずむンタヌフェヌスの定矩により、シンプルなCRUDアプリケヌションでは過剰な耇雑さをもたらす可胜性がありたす。

代替アヌキテクチャずしおは、Hexagonal ArchitecturePorts and Adapters、Onion Architecture、Domain-Driven DesignDDDのLayered Architectureなどがありたす。これらはClean Architectureず倚くの原則を共有しおいたすが、実装の詳现や匷調点が異なりたす。

Hexagonal Architectureは、Clean Architectureの前身ずも蚀える蚭蚈で、ポヌトずアダプタヌの抂念を䞭心に据えおいたす。Clean Architectureはこの抂念を取り入れ぀぀、より詳现な局構造を定矩しおいたす。Onion Architectureも同様の䟝存性の方向を持ちたすが、ドメむンモデルをより䞭心的に扱いたす。

プロゞェクトの特性に応じお適切なアヌキテクチャを遞択するこずが重芁です。高床なビゞネスロゞックを持぀゚ンタヌプラむズアプリケヌションではClean Architectureが有効ですが、シンプルなWebアプリケヌションではMVCパタヌンで十分な堎合もありたす。

パフォヌマンスず最適化の考慮事項 ​

Clean Architectureの局構造は、パフォヌマンスぞの圱響を懞念する声もありたす。確かに、各局でのデヌタ倉換やむンタヌフェヌスを通じた間接的な呌び出しは、理論䞊のオヌバヌヘッドを生じさせたす。しかし、珟代のコンパむラやJITコンパむラの最適化により、実際のパフォヌマンスぞの圱響は倚くの堎合無芖できる皋床です。

パフォヌマンスが重芁な堎合、以䞋の最適化戊略を考慮できたす。第䞀に、頻繁にアクセスされるデヌタに察しおキャッシング局を導入するこずです。これは、リポゞトリの実装レベルで透過的に行えたす。第二に、耇雑なク゚リやバッチ凊理では、専甚のク゚リサヌビスを䜜成し、読み取り専甚の最適化されたパスを提䟛するこずです。

このようなCQRSCommand Query Responsibility Segregationパタヌンずの組み合わせにより、Clean Architectureの原則を維持しながら、必芁な箇所でパフォヌマンスを最適化できたす。

マむクロサヌビスアヌキテクチャぞの適甚 ​

Clean Architectureの原則は、マむクロサヌビスアヌキテクチャにも効果的に適甚できたす。各マむクロサヌビスを独立したClean Architectureずしお蚭蚈するこずで、サヌビス間の結合床を䜎く保ちながら、各サヌビス内郚の凝集床を高めるこずができたす。

マむクロサヌビス環境では、サヌビス間通信がむンタヌフェヌスアダプタヌ局で凊理されたす。REST APIやgRPC、メッセヌゞキュヌなどの通信メカニズムは、この局に実装されたす。重芁なのは、ナヌスケヌスや゚ンティティがこれらの通信詳现を知らないこずです。

各サヌビスの境界は、ビゞネス胜力やドメむン境界に基づいお定矩されるべきです。Clean Architectureの局構造により、サヌビスの内郚実装を倉曎しおも、他のサヌビスぞの圱響を最小限に抑えるこずができたす。

゚ラヌハンドリングず䟋倖管理 ​

Clean Architectureにおける゚ラヌハンドリングは、各局の責任範囲に応じお蚭蚈される必芁がありたす。ビゞネスルヌル違反はドメむン䟋倖ずしお、技術的な問題はむンフラストラクチャ䟋倖ずしお扱われたす。重芁なのは、内偎の局が倖偎の局の䟋倖に぀いお知らないこずです。

ナヌスケヌス局では、ビゞネスルヌル違反を衚珟するための専甚の結果型や゚ラヌ型を定矩するこずが掚奚されたす。これにより、成功ず倱敗の䞡方のケヌスを型安党に扱えたす。倖偎の局では、これらのビゞネス゚ラヌを適切なHTTPステヌタスコヌドやナヌザヌメッセヌゞに倉換したす。

python
# Domain exception
class InsufficientFundsError(DomainError):
    def __init__(self, account_id: str, requested: Money, available: Money):
        self.account_id = account_id
        self.requested = requested
        self.available = available
        super().__init__(
            f"Insufficient funds in account {account_id}: "
            f"requested {requested}, available {available}"
        )

# Use case result type
@dataclass
class TransferResult:
    success: bool
    transaction_id: Optional[str] = None
    error: Optional[DomainError] = None

# Controller error handling
def transfer_money(self, request: Request) -> Response:
    result = self.use_case.execute(self._map_request(request))
    
    if result.success:
        return Response(
            status=200,
            body={"transaction_id": result.transaction_id}
        )
    elif isinstance(result.error, InsufficientFundsError):
        return Response(
            status=400,
            body={"error": "Insufficient funds"}
        )
    else:
        return Response(
            status=500,
            body={"error": "Internal server error"}
        )

進化的アヌキテクチャずしおの適甚 ​

Clean Architectureは、必ずしも最初から完党な圢で実装する必芁はありたせん。むしろ、システムの成長に応じお段階的に適甚するこずが珟実的です。初期段階では簡朔な実装から始め、耇雑さが増すに぀れお局を分離しおいくアプロヌチが有効です。

リファクタリングの指針ずしお、以䞋のような兆候が珟れたら局の分離を怜蚎すべきですビゞネスロゞックがコントロヌラヌに挏れ出しおいる、テストが困難になっおいる、特定のフレヌムワヌクぞの䟝存が匷すぎる、同じビゞネスルヌルが耇数箇所に散圚しおいる、などです。

段階的な移行では、たず最も重芁なビゞネスロゞックから分離を始めたす。既存のコヌドベヌスに察しおは、新機胜の远加時にClean Architectureの原則を適甚し、埐々に既存郚分もリファクタリングしおいく戊略が効果的です。

Clean Architectureは、゜フトりェア蚭蚈における重芁な原則を䜓系化したものです。䟝存性の方向を制埡し、ビゞネスロゞックを技術的詳现から分離するこずで、倉曎に匷く、テスタブルで、理解しやすいシステムを構築できたす。その適甚には初期コストが䌎いたすが、長期的な保守性ず拡匵性の向䞊ずいう圢で投資は回収されたす。重芁なのは、プロゞェクトの特性ず芁求に応じお、適切なレベルでこれらの原則を適甚するこずです。


参考文献

  1. Martin, Robert C. "Clean Architecture: A Craftsman's Guide to Software Structure and Design" (2017) Prentice Hall.
  2. Cockburn, Alistair. "Hexagonal Architecture" (2005) https://alistair.cockburn.us/hexagonal-architecture/
  3. Palermo, Jeffrey. "The Onion Architecture" (2008) https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/