게터와 세터를 피하고 사용자 정보를 표시하십시오.


10

배경

나는 "Clean Code book"을 읽고, 병렬로, 은행가 계좌와 같은 카스 테 닉 객체 Kata를 작업하고 있으며 그 규칙을 고수하고 있습니다.

calisthenic 객체의 9 번째 규칙은 getter 또는 setter를 사용하지 않는 것입니다.

꽤 재밌는 것 같고이 원칙에 동의합니다. 또한 Clean Code 98-99 페이지에서 저자는 getters / setter가 추상화를 깨뜨리고 객체를 요구할 필요는 없지만 객체를 알려야한다고 설명합니다.

이것은 내 마음에 완벽하게 적용되며이 원칙에 전적으로 동의합니다. 실제로 문제가옵니다.

문맥

예를 들어, 일부 사용자를 나열하고 사용자 세부 정보를 표시해야하는 응용 프로그램이 있습니다.

내 사용자는 다음으로 구성됩니다.

-> Name
   --> Firstname --> String
   --> Lastname --> String
-> PostalAddress
   --> Street --> String
   --> PostalCode --> String

문제

간단한 정보 만 표시하고 ( 특정 필드에서 추가 작업이 필요하지 않음을 확인 해야하는 경우) Getter를 피하기 위해 어떻게해야합니까? Firstname 값을 단순하게 표시하려면 ( 무작위) 출력 지원?

내 마음에 떠오르는 것

한 가지 해결책은 다음을 만드는 것입니다.

user.getName().getFirstName().getStringValue()

그것은 끔찍한 일이며, 많은 칼레 스테 닉 물체의 규칙을 어 기고 데메테르 법칙을 어기는 것입니다.

다른 하나는 다음과 같습니다.

String firstName = user.provideFirstnameForOutput();
// That would have called in the user object =>
String firstName = name.provideFirstnameForOutput();
// That would have called in the name object =>
String firstName = firstname.provideFirstnameForOutput();

그러나이 솔루션에 익숙하지 않습니다. 데메테르 법칙 만 일치시키는 방법으로 표준 게터 / 세터를 우회하는 것과 같은 "고차 접근 자"인 것 같습니다 ...

어떤 아이디어?

답변:


17

게터와 세터를 피하는 아이디어에 대한 일반적인 오해는 어디에서나 피하는 것입니다. 사용자와 상호 작용하는 아키텍처의 표면에 올 때 불가능합니다.

컨텍스트를 제공하는 집계를 사용하여 오브젝트를 보호해야하며 메소드는 명령으로 작동해야하는 애플리케이션의 비즈니스 논리 부분에서 getter 및 setter를 사용하지 않아야합니다.

게터와 세터를 피하기 위해 관찰 가능한 엔터티를 통해보고 시스템을 구현 하는 반응 형 프로그래밍 과 유사한 솔루션을 디자인 할 수 있지만, 이는 디자인이 사용자 인터페이스에 실제로 우수하더라도 아키텍처를 극도로 복잡하게하고 CRUD 수준의 응용 프로그램에서는 의미가 없습니다.

getter / setter 사용을 고려해야하는지 여부는 전적으로 현재 작업중인 응용 프로그램의 일부에 달려 있습니다. getter를 사용하는 사용자 인터페이스가 비즈니스 로직의 경우, getter를 통해 검색된 값을 기반으로 코드의 일부를 실행하는 것이 좋습니다. getter를 호출하는 클래스).

또한 demeter의 법칙은 점을 세는 것이 아니라 클래스에서 게터를 사용하여 액세스 할 수없는 구성 요소를 가져 와서 컨텍스트 제공 클래스를 분리하는 것입니다.

비즈니스 모델 내에서 사용자 인터페이스가 너무 깊다고 생각되면 모델의 특정 부분을 시각적 표현으로 변환하는 데 뷰 모델을 시스템에 도입 할 수 있습니다.


좋아, 그 제안은 도메인 엔터티 사이의 매퍼처럼, 접근자가 필요한 프리젠 테이션 레이어의 사용자 지정 DTO에 대한 것 같아?
mfrachet

@Margin 그렇습니다.
Andy

정말 좋은 부드러운이 모든 계단식 물건 소리, 대답을 주셔서 감사합니다)
mfrachet

2

생각할 한 가지 방향은 원시 데이터에 대한 액세스를 제공하는 대신 일반 문자열 형식화 멤버 함수를 제공하는 것입니다. 이 같은:

String lastName = user.formatDescription("$(Lastname)");
String fullName = user.formatDescription("$(Lastname), $(Firstname)");
String abbreviated = user.formatDescription("$(FnAbb). $(LnAbb).");

이 접근 방식을 사용하면 전체 데이터를 그대로 제공하는 데 제한을 두지 않고 편리하고 의미있는 방식으로 데이터를 변환하는 수단을 제공 할 수 있습니다. 예를 들어, 대소 문자를 사용하여 트릭을 수행해야 할 수도 있습니다.

String accountName = user.formatDescription("$(firstname).$(lastname)");

일반적으로 사용되는 복잡한 형식을 한 번 정의 할 수도 있습니다. 예를 들어

String fullAddress = user.formatDescription(User.kAddressFormat);

이 방법의 장점은 개별 문자열을 User클래스 내부에 유지 하면서 실제로 호출 코드에 훨씬 더 많은 기능을 제공한다는 것입니다. 그러나 단점은 formatDescription()몇 줄의 코드가 될 템플릿 메커니즘을 구현해야한다는 것 입니다.

따라서 이것은 완전한 과잉 일 수 있습니다. 프로그래밍 원칙은 지침 일뿐입니다. 그리고 다른 원칙을 따르는 것이 KISS 원칙을 위반할 때마다 간단한 방법으로 수행하는 것이 가장 좋습니다. 따라서 이러한 서식 지정 멤버가 적어도 필요하지 않은 한 접근 자 기반 접근 방식을 사용하여 단순화를 위해 구현하지 않아도됩니다.


5
그러나 이것은 나에게 SRP 위반으로 보입니다. User템플릿 언어를 구문 분석하고 컴파일 / 해석하는 것은 실제로 객체 의 책임 입니까?
Jörg W Mittag

@ JörgWMittag 반드시 그런 것은 아닙니다. 내가 말했듯이, KISS 원칙이 우선합니다. 그리고 User클래스 가이 기능 자체를 구현 해야한다고 아무 말도하지 않았습니다 . 그러한 기능이 필요한 클래스가 두 개뿐이라면 템플릿 대체 메커니즘을 자체 클래스로 고려하여 내기를 걸 수 있습니다. 이것은 User실제로 데이터 컨테이너 이상의 수준으로 제공 되는 추상화를 해제하는 방법의 예입니다 . 그리고 나는 그것이 접근자를 피하는 것이 전부라고 믿습니다 struct. 다발을 처리하는 대신 OOP를 수행하는 것입니다 .
cmaster-복원 monica

KISS가 완전히 주관적이고 SRP 목표라는 것을 알고 있습니까? KISS는해야 할 일에 대해 아무 것도 말하지 않습니다. 그리고 당신에게 "단순"이란 것이 "단순"하지 않을 수도 있습니다. KISS 또는 SRP와 논쟁 할 때 품질이 실제로 다릅니다.
oopexpert
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.