존재하지 않는 경우 get에 무언가를 작성하는 것은 나쁜 코딩 습관입니까?


18

그래서 getAccount계정에 식별자를 가져 오는 경우 식별자를 반환하는 예외 와 같은 웹 서비스가 있습니다 . 가져 오기와 동일한 정보로 예외가 발생하면 클라이언트는 항상 계정을 만들고 싶어합니다.

내부의 모든 웹 서비스 호출을 처리 할 클라이언트를 위해 편의 라이브러리를 만들고 있으므로 호출 자체를 수행하는 방법을 알 필요가 없습니다.

내가 궁금한 것은 getAccount(accountName)계정이있는 경우 계정을 가져 오는 계정을 만들고이 계정을 만들고 정보를 반환하지 않는 경우이 라이브러리에 있다는 것입니다. 예외를 처리하기 위해 클라이언트에 남겨 두거나 getOrCreateAccount와 같은 이름을 지정해야합니까? 상관이 있나?

get 작업에서 무언가를 만드는 것은 나쁜 습관입니까?


9
최소한 나는 그 getOrCreateAccount와 비슷한 이름을 지을 것입니다.
Telastyn

4
지연 초기화 컨텍스트에서 유효 해 보입니다. 그러나 라이브러리에서 해당 패턴을 사용해야하는지 여부에 따라 다릅니다.
Chris C

1
나는 같은 동사 acquire를 좋아한다 acquireAccount. 그것은 내가 만난 주요 프로토콜에서 기존 의미를 가지고 있지 않으며, 그것에 잘 맞는 명령 적 고리가 있습니다. "나를 위해이 중 하나를 획득하기 위해해야 ​​할 일은 무엇이든하십시오. 요청, 구축, 위조, 도용, 상관 없어요, 그냥 가져 가거나 죽어 가기 만하세요."
Dan Ross

2
"고객은 항상 계정을 만들고 싶어합니다."-매우 드문 것 같습니다. 사용자가 사용자 이름을 잘못 입력하여 계정을 얻을 수없는 경우, 이름이 잘못 입력 된 계정을 만들고 싶지 않습니다.
gnasher729 8

javabean 사양에 따르면 oracle.com/technetwork/articles/javaee/spec-136004.html getSomething() 은 게터 setSomething()용이며 세터 용입니다. 이모 더 지적 무언가를 아무것도 즉, 뭔가 다른 호출해야합니다 fetchSomething, obtainSomething, computeSomething, 또는 doSomethingElse
ccpizza

답변:


31

그렇습니다. 제 생각에는 창조의 힘을 가진 것으로 문서화되지 않은 절차에서 무언가를 창조하는 것은 일반적으로 나쁜 습관입니다. 어느 절차의 이름을 getOrCreate...하거나 별도의이 create...절차를 다음과 같은 경우 정말 원하는하는이 getOrCreate...첫 번째 시도 get...하고, 실패 할 경우, 전화를 create...한 후 호출 get....

라이브러리 사용자 get...는 get 조작이 실패하면 프로 시저가 작성 될 것으로 예상하지 않을 수 있습니다. 테스트 결과 get...전체 톤의 데이터 가 생성 되었다는 사실을 갑자기 알게 되면 아마 놀랄 것입니다. 그리고 그들은 어떻게 그것을 청소합니까? 그들이는 경우가 오류를 얻을 것이다 코드의 생각을 작성하는 경우 get...실패는 그들이 것을 처리하는 그들의 방법은?


고맙게도 create는 실제로 get도 반환 할 id를 반환하므로 get... create... get...처음 두 개만 수행 할 필요는 없습니다 . 고객에게 전화를 걸지 get않고 단순히 전화를 걸 수있는 능력이 필요한지 여부에 대해 이야기하겠습니다.
Mike

6
@ Mike : 여전히 create이름에 있어야한다고 생각합니다 . 현재 일어나는 일에 대해 100 % 명확해야합니다.
FrustratedWithFormsDesigner

그렇습니다. 나는 원래의 생각은 그냥하는 것이기 때문에 getOrCreate의 라인을 따라 무언가를 만들 계획이지만, 그것이 배경에서 무언가를 창조하고 있다는 것이 즉시 명확하지 않다는 것을 깨달았습니다.
Mike

1
이것은 매우 늦었지만 getOrCreate널리 사용되는 웹 프레임 워크에서 우선합니다 : docs.djangoproject.com/en/1.10/ref/models/querysets/…
tex

18

아니요, '나쁜 습관'이 아닙니다. 귀하와 다른 개발자가 귀하가 원하는 방식으로 동의하는 한 괜찮습니다. 결국, 그것은 당신이 원하는 계정을 반환 할 것입니다. 계정이 '후드'아래에 생성되었다는 것은 발신자와 관련이 없습니다.


10
공개적으로 사용 가능한 API 인 경우는 예외입니다. 더 큰 공동체는 GET이 무능력하고 무능하다는 데 이미 동의했다. 즉, 매번 동일한 작업이 수행되며 서버 상태를 변경하지 않는 안전한 방법입니다. 이것은 REST Wiki에 있습니다. 그 외에도 API가 자신의 작은 세계에 존재하는 경우 그룹이 허용하는 모든 작업을 수행하십시오.
jmort253

9
공개 API의 경우 API가 무엇을 해야하는지 에 관계없이 의미가있는 한 괜찮습니다 . 단일 항목이 트릭을 수행 할 때 API에서 여러 항목을 작성하는 데는 별다른 의미가 없습니다.
GrandmasterB

기록을 위해 그것은 완전히 내부 라이브러리이며 나는 그것을 사용하는 방법을 사용하여 팀에 말할 수있는 능력이 있습니다
Mike

1
@ jmort253 : 서비스가 클라이언트 에게 부작용이 보이지 않으면 nullipotent 입니다. 서버는 원하는대로 할 수 있습니다.
kevin cline

1
@ kevincline, 나는 신용 카드를 청구하는 측면에서 그것에 대해 생각하고 있다고 생각합니다. 서버가 GET 요청에 따라 카드를 충전하지만 실행할 때마다 "거부 됨"과 같은 결과를 제공하면 GET 정신에 위배되는 것처럼 보입니다. 그 말로, 나는 당신의 요점을 봅니다. 서버는 GET 요청 수를 계산하고 3 번의 쿼리 후에 나를 잠글 수 있으므로 속도를 제한하지만 계정 세부 정보를 변경하지 않아도됩니다. 서버 상태가 수정되지 않았다고 말할 때 중요한 차이점이라고 생각합니다. 아마도 내가 대신 "클라이언트 상태 서버의"말해야한다
jmort253

10

getAccount()항상 계정을 반환 할 수 있으면 호출자의 관점에서 계정이 존재하며 항상 존재합니다. getAccount()아무것도 '생성' 할 필요가 없습니다 . 계정은 기본 계정과 다를 때까지 어디에도 저장하지 않아도됩니다.


+1 일반적으로 GetOrCreate잘못된 의미론 이지만 물리적으로 존재하는지 여부에 관계없이 "논리적으로"존재할 수있는 객체를 얻는 것이 좋습니다. 예를 들어, 가변 항목의 희소 배열에는 요소 1,841,533에 할당 된 스토리지가 없지만 새 오브젝트를 작성하고 저장 한 후 참조를 리턴하여 해당 요소를 "검색"할 수 있습니다.
supercat

4

세 가지 방법을 만드는 것이 가장 좋습니다.

getAccount-> 계정을 가져옵니다.

createAccount-> 계정을 만듭니다.

getAccountAndCreateIfNeeded-> 나만의 이름 지정;)

분리 이유 : 가져오고 생성하는 간단한 방법이 있습니다. 그것은 두 가지 모두에 대해 확실한 테스트 가능한 방법입니다. getAccount의 경우 계정을 찾지 못하는 것은 예외가 아닙니다 . 따라서 거짓 또는 그와 비슷한 것을 반환하면 예상됩니다.

그런 다음 그룹화 된 함수 getAccountAndCreateIfNeeded에서 해당 반환 값을 사용할 수 있습니다. 이제 테스트 가능하며 항상 계정을 반환해야합니다. 뭐든지 물어봐

이 세 가지 방법은 모두 명확합니다. 수행 한 작업과 반환하는 작업이 모두 명확합니다. 당신은 지금 당신의 팀과 계약을 할 수 있지만 이런 종류의 예외는 장기적으로 끔찍합니다. 아주 명확하게하면 아무 문제가 없습니다.


또한 Clean Code에서 : "메서드가 의미하는 바를 수행 할 수없는 경우 예외를 발생시킵니다." 'GetOrCreateIfneeded'에 Try / Catch 블록이있어 실패한 GET을 throw 한 다음 실패한 get에 대해 예외 유형이 다시 발생하면 Throw 안에 'createAccount'가 있습니다.
Graham

네 번째 방법 :을 제안 할 수 있습니다.이 방법 getAccountIfExists은 계정을 얻거나 새 방법을 만들지 않으면 계정이 존재하지 않음을 나타냅니다. getAccount방법 자체는 계정이 있는지 전제로하고 예외를하지 않을 경우 던져해야합니다.
supercat

2

상황에 따라 다릅니다.

예를 들어 지연로드 / 인스턴스화를 수행하여 실제로로드 될 때까지 데이터로드 또는 인스턴스 생성을 지연시킬 수 있습니다. 이것은 필요하지 않은 리소스를 절약하기 때문에 일반적으로 합리적입니다 (클래스 / 데이터가 필요하지 않으면로드되지 않습니다).

그러나이 특별한 경우, 계정이 없으면 getAccount라는 메소드를 사용하여 새 계정을 만드는 것은 좋은 습관이 아니라고 말합니다. 사용자가 특정 계정을 식별하기 위해 몇 가지 자격 증명을 제공했지만 해당 계정을 찾을 수없는 경우 사용자가 아직 고객이 아니고 해당 계정을 생성했거나 자격 증명이 잘못 입력되었다는 의미입니까? 사용자는 입력하려는 내용을 입력했는지 확인해야합니다.

새 계정을 식별 할 수없는 경우 새 계정을 작성하는 getAccount 메소드가있는 경우 문제를 선택할 수 없습니다. 계정 생성과 계정 가져 오기를 별도의 방법으로 분리하면 계정을 가져 오려는 시도가 실패 할 경우 수행 할 작업을 훨씬 유연하게 결정할 수 있습니다.

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