의존도를 낮추고 서로에게 주는 영향을 감소함으로써 유지보수의 용이성 향상.
덕에 낮은 비용으로 새로운 기능 추가 용이.
출처 : http://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
도메인 계층으로도 불리며, 엔티티 계층은 하나 이상의 프로그램 간에 공유될 수 있다는 가정하에 만드는 수명이 긴 객체.
(즉, 재사용의 가능성이 높다는 것을 인지하고
외부에 의해 변경될 가능성을 낮추어야 한다.)
이곳에는 Enterprise 규모의 비즈니스 데이터를 포함하거나
핵심이 되는 비즈니스 규칙을 캡슐화합니다.
애플리케이션 계층으로도 불리며, 어플리케이션 규모의 비즈니스 규칙을 포함합니다. 이 레이어의 변경사항은 엔티티에 영향을 미쳐서는 안되며,
인프라 단의 DB나 UI, 라이브러리와 같은 외부요소에 의해
영향을 받지 않는다는 것을 원칙.
이는 즉, 해당 계층의 수정은 응용 프로그램의 동작에 영향을 미친다는 의미.
어뎁터 계층은 DB나 Web, UI와 같은 바깥 계층에서 사용하기 편리하도록,
유즈케이스 또는 엔티티 계층에서 데이터를 변환하는 어뎁터의 집합.
흔히 MVC, MVVM과 같은 아키텍처를 포함하는 것이 이 영역으로
컨트롤러, 프레젠터, 게이트웨이 등이 속합니다.
인프라 계층이라고도 불리며, 가장 외부에 있는 레이어로 DB, 웹 프레임워크와 같은 세부 정보(Details)를 나타내는 계층.
이곳은 보통 글루 코드(Glue code)만 작성하며, 시간이 지남에 따라 구성이 변경될 수 있으므로 엔티티 계층(또는 도메인 계층)에 추상화(abstracted)하여 도메인 계층에 영향을 주지 않고 인터페이스를 수정하고 업데이트할 수 있음.
users/
|-- domain/
| |-- entities.py
| |-- use_cases.py
|-- repositories/
| |-- user_repository.py
|-- views/
| |-- user_views.py
|-- models.py
|-- serializers.py
from django.db import models
class User(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField(unique=True)
class UserEntity(object):
def __init__(self, id=None, username=None, email=None):
self.id = id
self.username = username
self.email = email
class CreateUserUseCase(object):
def __init__(self, user_repository, serializer_class):
self.user_repository = user_repository
self.serializer_class = serializer_class
def execute(self, user_entity):
user = self.user_repository.save(user_entity)
return self.serializer_class(user)
class ListUsersUseCase(object):
def __init__(self, user_repository, serializer_class):
self.user_repository = user_repository
self.serializer_class = serializer_class
def execute(self):
users = self.user_repository.get_all()
return self.serializer_class(users, many=True)
from .models import User
class UserRepository:
def save(self, user_entity):
user = User.objects.create(username=user_entity.username, email=user_entity.email)
return user
def get_all(self):
return User.objects.all()
from rest_framework import serializers
from .domain import entities
class UserSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
username = serializers.CharField()
email = serializers.EmailField()
def create(self, validated_data):
return entities.UserEntity(**validated_data)
from rest_framework import viewsets, mixins, status
from rest_framework.response import Response
from .domain import use_cases, entities
from .repositories import UserRepository
from .serializers import UserSerializer
class UserViewSet(viewsets.GenericViewSet,
mixins.CreateModelMixin,
mixins.ListModelMixin):
queryset = User.objects.filter()
serializer_class = UserSerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
use_case = use_cases.CreateUserUseCase(UserRepository(), self.get_serializer)
result_serializer = use_case.execute(serializer.save())
return Response(result_serializer.data, status=status.HTTP_201_CREATED)
def list(self, request, *args, **kwargs):
use_case = use_cases.ListUsersUseCase(UserRepository(), self.get_serializer)
result_serializer = use_case.execute()
return Response(result_serializer.data)