메소드의 매개 변수 목록에 객체 또는 객체 식별자가 포함되어야합니까?


10

우리 팀은 다음과 같은 토론을하고 있습니다.

다음 두 가지 방법이 있다고 가정 해 봅시다.

public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);

public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);

유선으로 전송되는 것은 ID입니다.

한쪽은 터미널과 클럽의 ID 만 가지고 있기 때문에 첫 번째 방법이 정확하다고 말하고 다른 것이 없다는 것이 분명해야합니다.

다른 쪽은 두 번째 방법이 더 유연하기 때문에 정확하다고 말합니다.

우리는 객체 매개 변수 아이디어에 익숙하고, 다른 쪽은 객체 매개 변수가 객체를 속성으로 가져야한다고 생각합니다.

올바른 방법은 무엇입니까?

세 번째로 더 나은 접근법이 있습니까?


무엇? .........
James

1
문맥? 웹 서비스? WCF?
코드 InChaos

1
@James-죄송합니다.이 질문을 약간 빨리 작성했습니다. 이해할 수없는 부분을 알려 주시면 수정할 수 있습니까?
Mithir

@CodesInChaos 방법은 실제로 BL 방법입니다
Mithir

답변:


10

답은 상황에 따라 다릅니다.

클라이언트가 모든 객체를 이미 사용할 수 있다고 예상 되면 객체 매개 변수를 사용합니다. 그렇지 않으면 코드가 필요 이상으로 복잡해 보입니다. 예 club.getId()를 들어, 같은 전화 를받습니다.

클라이언트가 ID를 쉽게 사용할있다면, 두 번째 방법이 더 좋을 것입니다. 실제로 ID 만 필요한 경우 클라이언트가 모든 객체를 조립 /로드하지 않아도 될 수 있습니다.

옵션은 두 가지 방법을 모두 제공하는 것이므로 클라이언트는 사용할 방법을 선택할 수 있습니다 (API가 복잡해지지 않는 경우)

일반적으로 객체 매개 변수는 확장 성이 뛰어납니다. 향후 작업을 수행하기 위해 다른 데이터 조각이 필요한 경우 추가 정보를 얻는 다른 방법을 도입 할 필요가 없기 때문입니다.

마지막으로 분석법 서명은 분석법이 수행하는 작업의 세부 사항 (귀하의 경우 정확하게 전달되는 내용) 에 의해 지시되지 않아야합니다 . API는 추상적으로 의미가 있으므로 구현이 변경되면 문제가 발생하지 않습니다.


3
+1 한 가지만 더 추가하겠습니다. 원격으로 ( "와이어를 통해"?) 호출되는 메서드의 경우, 객체를 전달하면 광범위한 객체 트리를 깊이 직렬화 할 수 있습니다. ID는 원격 호출 페이로드의 크기가 염려 될 때 객체를 대체 할 수있는 훌륭한 방법입니다.
로스 패터슨

1
이 경우 일련의 추상화에 결합 된 것처럼 보이므로 Id를 전달하면 더 많은 유연성을 사지 않을 것이고 매개 변수를 뒤집을 가능성이 높아질 것입니다. 문제는 메소드의 코드가 내가 전달하는 추상화와 얼마나 밀접하게 결합되어 있습니까? 예를 들어 "validateCreditCard (string card, string cvi)"와 같은 방법은 아마도 어떤 종류의 CreditCard 객체와 밀접하게 연결되지 않도록 프리미티브와 함께 있어야합니다.
ipaul

중간에 만나 매개 변수 목록에서 인터페이스를 사용합니다. 그러면 클럽은 클럽이 될 수 있지만 미래에는 사우나가 될 수도 있습니다.
Pieter B

13

첫 번째 접근법은 원시 강박 관념을 나타냅니다 . 당신이 주변의 int 문자열을 전달하기 때문에, 그건 아주 (예를 들어,이 terminalId 매개 변수에 clubId 전달) 프로그래머가 실수를하기 쉽다. 이로 인해 버그를 찾기가 어려워집니다.

두 번째 예에서는 터미널이 예상 될 때 클럽을 통과 할 수 없습니다. 이렇게하면 컴파일 시간 오류가 발생합니다.

그럼에도 불구하고 나는 여전히을 볼 것 string invoice입니다. 송장은 실제로 문자열입니까? 무슨 amount뜻입니까? 이것은 금전적 가치 일 가능성이 높습니다.

당신은 당신의 질문에 "무선으로 전송되는 것은 단지 ID입니다"라고 언급했습니다. 이것은 정확하지만이 요구 사항으로 인해 도메인이 흐려지지 않도록하십시오.

이 접근법을 선호하는 가장 좋은 설명은 Object Calisthenics의 규칙 3에 있습니다 .

int 자체는 스칼라 일 뿐이므로 의미가 없습니다. 메소드가 int를 매개 변수로 사용하는 경우 메소드 이름은 의도를 표현하는 모든 작업을 수행해야합니다. 동일한 방법으로 매개 변수로 시간이 걸리면 진행 상황을 훨씬 쉽게 확인할 수 있습니다. 이와 같은 작은 개체는 Hour 매개 변수를 사용하는 메서드에 Year를 전달할 수 없으므로 프로그램을 유지 관리하기 쉽게 만들 수 있습니다. 원시 변수를 사용하면 컴파일러는 의미 론적으로 올바른 프로그램을 작성하는 데 도움을 줄 수 없습니다. 작은 객체라도 객체를 사용하면 컴파일러와 프로그래머에게 값이 무엇이며 왜 사용되는지에 대한 추가 정보를 제공합니다.


그래서 두 번째 접근법이 선호됩니까? id 속성 만 채워진 클럽 객체가 있더라도?
Mithir

무작위 블로그 인 것 같습니다. 선호하는 것에 대한 증거는 없습니다. 누가 선호하는 것을 정말로 신경 쓰는가? 당신을 위해 일을 해
James

@James이 질문에 대한 명확한 답은 없습니다. 특히 OP가 많은 맥락을 제시하지 않았기 때문입니다. 한 가지 접근 방식이 다른 접근 방식보다 선호된다고 주장하는 사람은 OP를 장애로 처리하는 것입니다. 그 흑인과 백인이 아닙니다.
MattDavey

1
@James 나는 단지 첫 번째 접근 방식으로 버그를 찾기가 매우 어렵다고 지적했습니다. 기본 유형이 나쁜 것은 아니지만 기본 유형의 목적은 의미있는 도메인 유형을 구축하는 것입니다. 이 문맥 밖에서 그것들을 사용하는 것은 원시 강박 관념 냄새의 정의입니다.
MattDavey

5
@ 제임스 : MattDavey가 말한 것은 확립 된 사실입니다. 그는 네이티브 타입이 나쁘다는 것을 말하지 않고, 이것이 말하는 것입니다 : someMethod (int, int, int, int, string, decimal)는 someMethod (Club, Terminal, Card, String보다 클라이언트가 이해하고 사용하기가 훨씬 어렵습니다. , decimal)
c_maker

2

이것에 대한 정답은 없습니다. 작업에 적합한 옵션이 있습니다. 거의 모든 방법으로, 청구서 인수가 내 눈에 고랑을 일으켰습니다. 코드를 읽는 것이 무엇인지 전혀 알지 못합니다.

ID를 보내면 두 시스템은 그것이 나타내는 것과 밀접하게 연결되어야합니다. ClubID는 클럽 테이블의 핵심입니다. 더 중요한 것은 발신자와 피 호출자 모두 Clubs 테이블이 무엇인지, 어떤 데이터베이스에 있는지에 동의해야합니다. 해당 제약 조건을 적용하지 않거나 적용 할 수없는 경우 일반적인 설명을 사용하여 개체를 전달합니다. 네이티브, 직렬화, XML, 이름 = 값, ini 파일 :)

식별 한대로 "전선을 통해"비용이 발생합니다. 식별자를 보내는 것만으로도 다른 비용이 발생합니다. 어느 쪽이 당신을 가장 아프게하는지, 지금은 (혹은 나중에있을 수도 있습니다 ...) 선과 악의 지표입니다.

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