왜 데이터 클래스가 코드 냄새로 간주됩니까?


18

기사에서는 데이터 클래스가 "코드 냄새"라고 주장합니다. 이유:

새로 생성 된 클래스에 소수의 공개 필드 (및 소수의 getter / setter) 만 포함 된 경우에는 정상적인 현상입니다. 그러나 객체의 진정한 힘은 데이터에 대한 동작 유형이나 작업을 포함 할 수 있다는 것입니다.

객체가 데이터 만 포함하는 것이 왜 잘못 되었습니까? 클래스의 핵심 책임이 데이터를 나타내는 것이라면, 데이터에 대해 작동하는 메소드를 추가하지 않아도 단일 책임 원칙은 무엇입니까?


1
이것은 언어 기능에 크게 의존 할 것입니다. 예를 들어 파이썬에서 파이썬으로 자바를 작성하는 방법을 벗어나지 않는 한 "필드"와 접근 자 사이에는 차이가 없습니다 .
jscs

1
나는 일부 데이터 클래스 만있는 것은 그 자체로 코드 냄새가 아니라 생각하는 대부분의 수업은 우리가 안티 패턴은 "빈혈 도메인"에 대해 이야기하고 그런 경우 en.wikipedia.org/wiki/Anemic_domain_model
Tulains 코르도바

1
이 질문이 어떻게 중복되는지 알 수 없습니다. 다른 질문은 OO에서의 데이터 클래스 사용에 관한 것이며,이 질문은 완전히 다른 주제 인 데이터 클래스의 단점에 관한 것입니다.
Milos Mrdovic

리치 도메인 모델의 열등 성을 가정하고 입증 된 사실처럼 제시하는 여기에서 가장 많이 선정 된 답변보다 훨씬 차별화 된 stackoverflow에 대한이 답변을 읽을 수 있습니다. stackoverflow.com/questions/23314330/…
McLovin

답변:


31

순수한 데이터 객체를 갖는 것은 전혀 문제가 없습니다. 이 작품의 저자는 자신이 무슨 말을하는지 잘 모르고 있습니다.

이러한 사고는 "진정한 OO"가 프로그래밍하는 가장 좋은 방법이며 "진정한 OO"는 데이터와 기능이 혼합 된 "풍부한 데이터 모델"에 관한 것입니다.

현실은 특히 멀티 스레드 솔루션의 세계에서 실제로 그 반대가 사실임을 보여주었습니다. 불변의 데이터 객체와 결합 된 순수한 함수는 명백히 더 나은 코딩 방법입니다.


1
순수한 데이터 객체는 관계 모델링, 검증, 액세스 / 변경 제어에 매우 중요합니다.
Adrian

2
불변의 데이터 객체의 인스턴스만을 인수로 취하는 순수한 함수가 데이터 객체의 메소드로 구현되는 것이 좋지만.
RemcoGerlich

7
함수가 해당 데이터 유형의 인수를 사용하면 이미 데이터에 연결되어 있습니다.
RemcoGerlich

4
이것이 잘못되었거나 기껏해야 의견의 여지가 있기 때문에 하향 투표. OO 언어에서는 일반적으로 객체에 데이터 (불변 일 수 있음)와 그에 작용하는 메서드가 모두 포함되어있는 것이 좋습니다. 순수한 기능과 별도의 데이터는 다른 언어 패러다임에서 훌륭하지만 OO를 수행하는 경우 OO를 완전히 수행하십시오.
Marnen Laibow-Koser

3
현실은 우리에게 많은 것을 보여주었습니다. 독단적 지식-모두 "다른 사람들은 실패했다"는 의견에 -1. 또한 저자는 순수한 데이터 객체가 "잘못된"것이 아니라 단지 "코드 냄새"이며 의심 할만한 가치가 있다고 말합니다. 나는 내 나라를 위해 줄 하나의 공감대가 있다는 것을 유감스럽게 생각합니다. :-)
user949300

7

순수한 데이터 객체를 갖는 것은 전혀 문제가 없습니다. 필자는 내가 아는 소프트웨어 개발자가 공유하지 않은 의견을 가지고 있습니다.

특히 데이터베이스 맵핑의 경우 일반적으로 데이터베이스 및 게터 및 세터에 저장된 필드 만 포함하는 엔티티 클래스가 있습니다. Wikipedia 최대 절전 모드 (프레임 워크)

많은 툴 / 프레임 워크에서 사용하는 Java Bean의 핵심 아이디어는 필드와 관련 게터 및 세터 만 포함하는 Bean이라는 데이터 클래스를 기반으로합니다. Wikipdia JavaBeans

Fazit :
누군가가 '나쁜'또는 '코드 냄새'라고 주장하는 경우 항상 주어진 이유를 찾아야합니다. 그 이유가 다른 사람에게 더 나은 이유나 다른 의견을 요구하도록 설득하지 못하는 경우. (이 포럼에서 한 것처럼)


저자는 순수한 데이터 객체가 "잘못되었다"고 말하지 않습니다. 그들은 순수한 데이터 객체는 "코드 냄새"라고 말하는데, 이는 그것들을 사용하는 것에 대해 두 번 생각해야한다는 것을 의미합니다.
user949300

1
@ user949300, 혼란스러워 보입니다. 저자가 그것들을 코드 냄새로 언급하면, 그들에게 문제가있을 수 있음을 나타냅니다. 그들은 요즘 아주 좋은 관행으로 널리 인식되어 있기 때문에 분명히 코드 냄새가 아닙니다. 따라서 MrSmith42는 정확합니다. 절대적으로 아무런 문제가 없습니다.
David Arno

4

Martin Fowler의 좋은 주장 :

"Tell-Don't-Ask는 사람들이 객체 지향이 해당 데이터에서 작동하는 기능과 데이터를 묶는 것임을 기억하는 데 도움이되는 원칙입니다. 이는 데이터에 대해 객체를 요청하고 해당 데이터에 대해 행동하는 것이 아니라, 대신 객체에게해야 할 일을 알려 주어야합니다. 이는 데이터와 함께 동작을 객체로 옮기는 것을 권장합니다. "

https://martinfowler.com/bliki/TellDontAsk.html


1
여기서 문제는 Fowler가 더 넓은 범위를 요구하는 것에서 단지 객체 범위를 요구하는 것으로 기능을 변경함으로써 "tell do n't ask"를 인위적으로 제한한다는 것입니다. 그들은 여전히 ​​묻고 있습니다. "알지 말아라"는 사실 인수 목록을 통해 이러한 기능을 진정으로 말해줌으로써 한 걸음 더 나아갈 수 있습니다. 따라서 우리는 데이터 객체에 도달하고 "tell do n't ask"의 진정한 구현 인 별도의 (데이터 현명한) 기능을 제공합니다. 따라서 데이터 클래스가 코드 냄새라는 주장에 대한 좋은 주장이 아니라 오히려 그 반대를 증명합니다.
David Arno

2
@DavidArno 캡슐화와 숨기기를 잊고 있습니다. 객체에 멤버 메소드를 실행하도록 지시하면 멤버 메소드가 오브젝트의 블랙 박스로 이동하여 응답을 얻기 위해 필요한 모든 작업을 수행합니다. 외부에서 물체를 물으면 개인 상태에 접근 할 수 없으므로 물체가 현명한 것보다 더 많은 상태를 노출 시키거나 요구자가 필요한 것보다 더 많은 후프를 뛰어 넘어야합니다. OO 환경에서 왜 객체를 "구문"했는지 모르겠습니다. (다른 프로그래밍 패러다임은 물론 다른 접근법을 요구할 수도 있습니다.)
Marnen Laibow-Koser

2
@DavidArno 물론 정적 메소드에 매개 변수로 전달할 baz 있지만이를 위해서는 먼저 객체에 요청 해야 합니다. 아마도 함수형 프로그래밍과 같이 메소드가 기본이었던 프로그래밍 패러다임에서는 이것이 의미가 있지만, OO 환경에서는 객체가 기본적이며 그에 대한 데이터와 함수를 모두 포함해야하므로 절대 그렇지 않습니다. 객체에서 메소드를 제거한다고 캡슐화가 증가 했다는 주장 은 객체의 외부에 나타남을 의미하기 때문에 내가 알 수있는 한 정확하게 뒤로 향baz 합니다.
Marnen Laibow-Koser

1
@ MarnenLaibow-Koser, 저는 "OO를하고있다"고 주장하지 않습니다. 나는 코드를 작성하고 좋은 기술을 사용합니다. 이러한 기술이 기능적 패러다임, OO 패러다임, 또는 누가 준 패러다임에서 나온 것인지는 나에게 관심이 없습니다. 패러다임을 고르고 가능한 한 완벽하게 고집하는 것이 순수한 교리입니다. 나쁘다. 말도 안돼. 그것은 당신을 방해하고 열등한 코드를 초래합니다. 하지마
David Arno

1
@DavidArno 반대로 패러다임 (OO뿐만 아니라 괜찮은 패러다임)에 전념하면 강력한 고급 추상화와 논리적으로 일관성 있고 유지 관리 가능한 코드를 얻을 수 있습니다. 나는 이것이 독단적이 아니라 오히려 실용적이라고 말하고 있습니다. 필자는 저자와 같은 태도로 제작 된 코드를 너무 많이 보았습니다. 저는 저자가 사용중인 시스템의 논리적 일관성에 전념하지 않았습니다. 이해하기 어렵고 유지 관리하기가 어렵고 수정하기도 어렵습니다. 완벽한 패러다임은 없지만 일반적으로 신중하게 고려되지 않는 한 혼합물을 이해하기가 더 어렵습니다.
Marnen Laibow-Koser

2

이해해야 할 것은 두 가지 종류의 객체가 있다는 것입니다.

  • 동작 이있는 개체 . 이들은 대부분 / 모든 데이터 멤버에게 공개 액세스를 제공하지 않아야합니다. 이것에 대해 정의 된 접근 자 메서드는 거의 없습니다.

    예는 컴파일 된 정규식 될 것이다 : 개체 (특정 정규식에 대한 문자열을 일치하도록하고, (부분) 일치를보고) 특정 동작을 제공하기 위해 생성되지만 어떻게 컴파일 된 정규식이하는 그 작업은 사용자의 하나도 없다 사업.

    내가 쓰는 대부분의 수업은이 범주에 속합니다.

  • 실제로 데이터 인 객체 . 이들은 모든 회원을 공개적으로 선언해야합니다 (또는 전체 접근자를 제공해야합니다).

    예를 들면 class Point2D입니다. 이 요구는이 클래스의 회원을 확보 할 것이라는 불변 절대적으로 없으며, 사용자는 단지를 통해 데이터에 액세스 할 수 있어야 myPoint.x하고 myPoint.y.

    개인적으로, 나는 그러한 클래스를 많이 사용하지 않지만, 내가 작성한 클래스 중 어딘가에서 사용하지 않는 더 큰 코드는 없다고 생각합니다.

객체 지향에 능숙 해지는 것은이 구별이 존재 함을 깨닫고 클래스의 기능을이 두 범주 중 하나로 분류하는 것을 배우는 것을 포함합니다.


C ++로 코딩하는 경우 class첫 번째 범주의 개체와 struct두 번째 범주를 사용하여이 구분을 명시 적으로 만들 수 있습니다 . 물론 두 class멤버는 기본적으로 모든 멤버가 비공개 인 반면 struct모든 멤버는 공개적으로 선언 한다는 점을 제외하면 동일합니다 . 정확히 의사 소통하려는 정보의 종류입니다.


1
downvote에 대한 설명은 멋질 것입니다 ...
cmaster-복원 모니카

답변 해주셔서 감사합니다. 사람들이 아무 이유없이 downvote 때 나는 그것을 싫어. 답변에 문제가있는 경우 이유를 설명하십시오 .
Sipo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.