두꺼운 모델 대. 비즈니스 로직, 어디에서 차별화를 이끌어 내십니까?


16

오늘 저는 데이터베이스 매핑 클래스에 메서드를 추가하는 방법과 위치에 대해 조직의 다른 개발자와 열띤 토론을 벌였습니다. 우리는 sqlalchemy데이터베이스 모델에서 기존 코드베이스의 주요 부분은 데이터베이스 테이블에서 파이썬 객체로 거의 기계적으로 변환되는 클래스 이름을 가진 매핑 된 속성 모음에 지나지 않습니다.

논점에서, ORM 사용의 주요 가치는 낮은 수준의 동작과 알고리즘을 매핑 된 클래스에 첨부 할 수 있다는 것이 었습니다. 모델은 먼저 클래스이고, 2 차적으로 영구적입니다 (파일 시스템에서 xml을 사용하여 지속적 일 수 있으므로 신경 쓸 필요가 없습니다). 그의 견해는 모든 행동은 "비즈니스 로직"이며, 데이터베이스 지속성에만 사용되는 지속적 모델을 제외한 모든 위치에 속해야한다는 것이었다.

필자 비즈니스 로직 무엇인지 구분해야한다고 생각합니다. 비즈니스 로직이 구현되는 방식의 하위 수준과 분리되어 있기 때문에 분리해야한다고 생각합니다. 도메인 로직은 모델 클래스에서 제공하는 추상화라고 생각합니다. 이전 단락에서 논쟁했지만, 나는 그것이 무엇인지에 손가락을 대는 데 어려움을 겪고 있습니다. API가 무엇인지 (우리의 경우 HTTP "ReSTful") 더 잘 이해할 수 있습니다. 사용자 는 수행 하려는 작업과 수행 할 수있는 작업 및 수행 방법과는 별도로 API를 호출 합니다. 끝난다.


tl; dr : ORM을 사용할 때 매핑 된 클래스에서 메소드에 어떤 종류의 것들을 사용할 수 있거나해야합니까, 또 다른 추상화 계층에 살려면 무엇을 제외해야합니까?


그것은 동시에 논의 된 두 가지 문제, 지속성 모델 의 문제 는 클래스이며 두 번째로 지속되는 것 같습니다 (파일 시스템에서 xml을 사용하여 지속 될 수 있으므로 신경 쓸 필요가 없습니다). 코드의 이유. 일반적으로 코드 작성 이유 ,이 요구 사항이 무엇인지 스스로에게 물어 보면 적어도 저에게는 분명합니다. 프로그램 작동 방식대한 고객 요구 사항입니까, 아니면 프로그램을 구현하기로 선택한 방식 입니까? 나를 위해 첫 번째는 비즈니스 논리이고 두 번째는 도메인 논리입니다. 이것이 도움이되는 방법.

답변:


10

나는 주로 당신과 함께 있습니다. 동료가 빈혈증 도메인 모델 반 패턴 또는 "지속성 모델"에서 모델을 복제하여 명백한 이점없이 주장하는 것 같습니다 (이 작업이 수행 된 Java 프로젝트에서 작업 중이며 대규모 유지 보수성 문제입니다. 모델에 변화가있을 때마다 3 배의 작업을 의미합니다).

ORM을 사용할 때 매핑 된 클래스의 메서드에서 어떤 종류의 작업을 수행 할 수 있어야합니까?

경험 법칙 : 클래스에는 모든 상황에서 사실 인 데이터에 대한 기본 사실을 설명하는 논리가 포함되어야합니다. 사용 사례와 관련된 논리는 다른 곳에 있어야합니다. 예를 들어 유효성 검사 는 Martin Fowler 의 흥미로운 기사에서 문맥에 따라 달라져야한다는 점을 지적합니다.


답의 두 번째 부분은 +1입니다. 첫 번째 부분에서, 빈혈 도메인 모델이 변경시 많은 '추가'작업이 필요하다고 말하는 이유가 확실합니다. 나의 이해는 변화가 어떤 방식 으로든 일어날 것이지만 여러 종류의 클래스 (나쁜 종류)에서 발생하지만 거의 같은 양의 변화입니다. 내 생각 엔?
NoChance

1
@ 에마 드 카림 (Emmad Kareem) :이 의견은 선창적인 지속성과 도메인 모델을 갖는 것에 관한 것이었다. 모델에 속성을 추가하려면 속성을 하나의 모델이 아닌 두 개의 모델 클래스에 추가하고 그 사이의 모든 맵 (이론적으로는 자동적 일 수 있지만 일반적으로 별도의 아이디어를 갖는 것이 좋다고 생각하는 어설 션)에 추가해야합니다. "지속성 모델"은 구분을 다르게하여 분리를 정당화하기로 결정합니다 (예 : DB 유형 모델과 더 일치하는 데이터 유형을 가짐). 변경 량의 2 + X 배이며, X는 0과 시간 사이의 불명확성으로 인해 생산성이 손실됩니다. 매핑 문제.
Michael Borgwardt

3

이것은 당신이 개발하고있는 것의 예상 크기와 규모에 따라 결정적인 판단입니다. 가장 엄격한 방법은 ORM 유형을 데이터 액세스 구성 요소로 제한하고 공통 라이브러리에서 POCO를 모든 계층에서 참조하고 사용하는 유형으로 사용하는 것입니다. 이것은 논리적 분리뿐만 아니라 미래의 물리적 분리를 가능하게합니다. UI와 비즈니스 로직 계층 사이에 추가 계층이 존재하도록 결정할 수도 있습니다. 이를 일반적으로 Facade 또는 Business Interface 레이어라고합니다. 이 추가 계층은 "사용 사례 코드"가있는 곳입니다. 느슨하게 결합 된 개별 코드는 Facade / BI 계층에 의해 호출됩니다 (예 : Facade에는 주문을 실제로 처리하는 데 필요한 모든 단계를 수행하기 위해 비즈니스 로직을 1 : M 번 호출하는 ProcessOrder () 함수가 있습니다).

그러나,이 모든 것이 말하고 있습니다 :이 정도의 아키텍쳐는 여러 번 불필요합니다. 예를 들어, 재사용을 위해 구성 요소를 패키징 할 의도가없는 간단한 웹 사이트를위한 코드를 작성하십시오. MVC 웹 사이트를 작성하고이 유형의 솔루션에 EF 오브젝트를 사용하는 것은 완벽하게 유효합니다. 나중에 사이트를 확장해야하는 경우 클러스터링 또는 "리팩토링"이라는 프로세스에서 종종 손실되는 프로세스를 살펴볼 수 있습니다.


3

동료에게 마치 마치 마치 마치 마치 자바 프로젝트 인 것처럼 모델을 오버 아키텍트 할 필요가 없음을 상기시켜주십시오. 두 개의 지속되는 객체를 비교하는 것은 동작이지만 지속성 레이어에 의해 지정된 것은 없습니다. 그래서 6 가지 맥주 문제는 왜 완전히 같은 관계가없는 클래스가 같은 것에 대해 설명 하는가? 물론, 지속성은 모델을 개별적으로 처리하기에는 충분하지만 모델이 다른 모든 것과는 별도로 처리되도록 보장하기에는 충분하지 않습니다. 자동차를 운전하거나 씻거나 파열하면 자동차를 항상 조작합니다.

그렇다면 왜이 모든 다른 측면을 단일 모델 클래스로 구성하지 않겠습니까? 지속되는 객체를 다루는 많은 클래스 메소드가 필요합니다. 하나의 클래스에 넣습니다. 유효성 검사를 처리하는 많은 인스턴스 메소드가 있습니다. 다른 메소드를 넣으십시오. 마지막으로 둘과 짜잔을 섞어주세요! 당신은 똑똑하고 자기 인식이 있고 완전히 포함 된 모델 표현을 가지고 있습니다.


1

다른 답변 외에도 ORM과 함께 풍부한 도메인 모델을 사용할 때 숨겨진 경고에주의하십시오.

다음 의사 코드와 같은 것을 달성하려고 할 때 지속 모델 클래스에 다형성 서비스를 주입하는 데 문제가있었습니다.

Person john = new Person('John Doe')
Organisation company = organisation_repository.find('some id')
Employee our_collegue_john = company.hire(john)

이 경우 조직은 HRService예를 들어 생성자 종속성으로 필요할 수 있습니다 . 일반적으로 ORM을 사용할 때는 모델 클래스의 인스턴스를 쉽게 제어 할 수 없습니다.

Symfony의 Doctrine ORM과 서비스 컨테이너를 사용하고있었습니다. 나는 우아하지 않은 방식으로 ORM을 몽키 패치해야했으며 지속성과 비즈니스 모델을 분리 할 수밖에 없었습니다. 나는 sqlachemy로 아직 시도하지 않았다. 파이썬은 이런 것들에 대해 PHP보다 더 유연 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.