ActiveRecord 패턴이 SOLID 설계 원칙을 따르거나 권장합니까?


43

Ruby on Rails로 유명한 ActiveRecord 패턴이 SOLID 설계 원칙 의 사용을 장려하는지 또는 권장하지 않는지에 관심이 있습니다 .

예를 들어 ActiveRecord 개체에는 도메인 논리와 지속성 논리가 모두 포함되어 있으며 이는 단일 책임을 위반하는 것입니다.


6
2009 년 Ruby Conference에서 SOLID Ruby Talk 가 끝난 Jim Weirich 는 "ActiveRecord 객체는 도메인 개념과 지속성 개념을 구현합니다. 이것이 SRP (Single Responsibility Principle)를 위반합니까?" 청중은 그것이 SRP를 위반한다는 데 동의합니다. 짐은 이것이 그들을 귀찮게하는지 묻습니다. 많은 청중이 그렇습니다. 왜? 테스트가 더 어려워집니다. 지속성 개체를 훨씬 무겁게 만듭니다.
David J.

답변:


56

ActiveRecord에 대한 몇 가지 유효한 비판이 있습니다. 항상 그렇듯이 Bob 아저씨 는 그것을 완벽하게 요약합니다 .

Active Record의 문제점은이 두 가지 매우 다른 스타일의 프로그래밍에 대해 혼동을 일으킨다는 것입니다. 데이터베이스 테이블은 데이터 구조입니다. 데이터가 노출되었으며 동작이 없습니다. 그러나 활성 레코드는 개체 인 것 같습니다. "숨겨진"데이터와 노출 된 동작이 있습니다. 데이터가 실제로 숨겨져 있지 않기 때문에“숨겨진”이라는 단어를 따옴표로 묶었습니다. 거의 모든 ActiveRecord 파생 상품은 접근 자와 변경자를 통해 데이터베이스 열을 내 보냅니다. 실제로, 활성 레코드는 데이터 구조처럼 사용됩니다.

반면에 많은 사람들이 비즈니스 규칙 방법을 Active Record 수업에 넣습니다. 그것들은 객체처럼 보입니다. 이것은 딜레마로 이어집니다. 액티브 레코드는 실제로 어느쪽에 있습니까? 대상입니까? 아니면 데이터 구조입니까?

Wikipedia는 테스트 가능성 문제 에서 비판을 요약합니다 .

OOP에서 캡슐화 개념은 종종 우려 분리 개념과 상충됩니다. 일반적으로, 분리를 선호하는 패턴은 분리 된 단위 테스트에 더 적합하지만 캡슐화를 선호하는 패턴은 API를 사용하기가 더 쉽습니다. Active Record는 데이터베이스없이 테스트하기가 어려운 시점까지 캡슐화를 선호합니다.

Ruby on Rails 구현을 위해 Gavin King은 다음과 같이 씁니다 .

이 시점에서 대부분의 개발자는 음, 생각하고 있습니다. 그렇다면 내 코드를 보면 회사가 어떤 속성을 가지고 있는지 어떻게 알 수 있습니까? IDE는 어떻게 자동 완성 할 수 있습니까? 물론, Rails 사람들은이 질문에 대한 빠른 답변을 얻을 것입니다. 데이터베이스 클라이언트를 시작하고 데이터베이스를 살펴보십시오!. 그런 다음 ActiveRecord의 자동 대문자 및 복수 규칙을 완벽하게 알고 있다고 가정하면 자체 Company 클래스의 속성 이름 을 추측 하여 수동으로 입력 할 수 있습니다.

또한 Ruby on Rails 구현에서 John Januszczak은 다음과 같이 씁니다 .

문제 # 1 : 정적 방법

...

어떤 사람들은 정적 메소드를 사용하는 것이 절차 적 프로그래밍에 불과하므로 객체 지향 디자인이 좋지 않다고 말합니다. 다른 사람들은 정적 메소드가 테스트 가능성으로 인한 사망이라고 말합니다.

문제 # 2 : 글로벌 구성 설정

...

따라서 필자의 예제에서 Account 클래스와 Account 인스턴스에 대한 종속성 주입없습니다 . 우리 모두가 지금 알아야 할 것처럼, 물건을 찾는 것은 매우, 매우 나쁩니다!

ActiveRecord 및 ORM이 일반적으로 반 패턴으로 간주되는 이유에 대한 몇 가지 추가 자료 :

ActiveRecord는 항상 매우 유용한 안티 패턴 처럼 느껴졌 지만 SRP와 종속성 반전 원칙에 위배된다는 데 동의합니다.


Rails 5+의 중요 업데이트 : "그리고 어떻게 IDE가 자동 완성 기능을 사용할 수 있습니까? 물론 Rails 직원은이 질문에 대한 빠른 답변을 얻을 수 있습니다. 데이터베이스 클라이언트를 실행하여 데이터베이스를 살펴보십시오!"는 유효하지 않습니다. 더 이상 속성 API를 사용하면 모델에서 사용 가능한 모든 열을 정의 할 수 있습니다.
Filip Bartuzi

6

(나는 ActiveRecord 클래스가 종속성 주입 가능성없이 구현되었다고 가정합니다).

개인적인 경험을 통해 ActiveRecord 패턴이 단위 테스트를 작성하는 데 주요 장애물이된다고 말할 수 있습니다. 단일 "ActiveRecord 클래스"에서 지속성 계층과 비즈니스 로직을 결합하면 단위 테스트를 작성할 수 없습니다 (먼저 리팩터링하지 않는 한). 따라서 유일한 옵션은 통합 테스트를 작성하는 것입니다. 이는 단위 테스트만큼 효과적이지 않습니다. 많은 ActiveRecord 클래스가있는 프로젝트를 인수 할 경우 특히 문제가됩니다. 유지하기 어려운 매우 복잡한 통합 테스트를 수행합니다.

따라서 ActiveRecord는 SRP와 거의 비슷하며 약간의 유지 관리 문제가 발생합니다. 단위 테스트를 작성하는 힘을 빼앗는 것 같습니다.

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