개인 메소드가 공개 메소드를 호출하면 코드 냄새가 나는가?


25

동일한 객체 인스턴스의 개인 메서드에서 공용 메서드를 호출하는 것이 코드 냄새입니까?


AAMOI 구체적인 예가 있습니까?
ocodo

아니요, 현재는 아닙니다. 내가 동료들과 논의한 사례를 기억했습니다. 여기에 의견을 남기고 싶었습니다.
Eimantas

5
일반적으로 문맥 상 약어를 알아낼 수 있지만 AAMOI는 꼭 찾아봐야했습니다
Carson Myers

@ 카슨-뭔가 찾았 어?
Eimantas

4
관심의 대상으로
카슨 마이어스

답변:


33

나쁘지 않은 냄새. 이것이 필요할 수 있습니다. 왜 이것이 잘못되었다고 생각하십니까? 원자 수준의 방법은 작업을 수행하는 독립 엔터티입니다. 작업을 수행하는 한 액세스 권한이있는 사람은 누구나 작업을 수행하기 위해 호출 할 수 있습니다.


동의한다. 일부 방법은 내부 및 외부 발신자 모두에게 유용한 기능을 제공합니다. 퍼블릭 메서드가 내부 구현에 매우 특정한 경우 적기가 발생할 수 있지만 모든 클래스가 내부를 숨기려는 것은 아닙니다. 예를 들어 컨테이너 추상 유형 레이어 아래에 데이터 구조 "도구"계층이있는 경우가 종종 있습니다. 이렇게하면 다른 컨테이너의 기본이되는 다른 데이터 구조에 일부 데이터 구조 코드를 재사용 할 수 있습니다.
Steve314

20

코드 냄새? 그렇습니다. 정말 나쁘지는 않지만 수업에 너무 많은 책임이 있다는 좋은 지표입니다.

클래스를 다른 객체로 나눌 필요가 있다는 표시로 사용하십시오. 개인 메소드는 실제로 깨끗한 OO 디자인에서 동일한 객체의 공용 메소드를 호출 할 필요가 없습니다.

물론 일단 클래스를 검사하고 메소드 호출의 이유가 명확 해지면, 그 클래스를위한 유틸리티 메소드가 사적인 것이지만 일반적으로 클래스에 대한 유틸리티 메소드가 유용 할 것입니다. 다른 방법으로 공개되고 활용되기 때문에 일반적으로 이러한 방법도 공개 될 것으로 기대합니다.

모든 코드 냄새와 마찬가지로, 이는 추가 코드 검사, 합리화 및 리팩토링에 대한 동기이지만 경보의 원인은 아닙니다.


5
'알람의 원인이 아님'은 +1입니다. 우리는 너무 많은 시간 동안 '냄새'를보고 생각없이 즉시 리팩터링 모드로 들어갑니다.
Michael K

SRP의 경우 +1 방금 장식 클래스가 장식자를 우회하여 자체 공용 함수를 호출했기 때문에 장식자가 작동하지 않는 경우가 발생했습니다. 해결책 : 클래스를 두 개로 나누고 장식 된 종속성을 주입하십시오.
Jon Hulka

18

이 클래스의 소스 코드를 읽지 않은 사람이 서브 클래스를 만들려고 시도하고 public 메소드를 재정의하면 불쾌한 놀라움이 발생할 수 있습니다. 그것이 진짜 관심사인지는 분명히 당신의 상황에 달려 있습니다. 아마도 당신은 공개적인 방법이나 수업의 최종 결정을 고려해야합니다.


왜? 덮어 쓴 공개 메소드가 불쾌한 놀라움을 불러 일으키면 누가 메소드를 호출했는지가 중요합니까?
user281377

4
그렇습니다. 한 공용 메서드를 재정의하면 다른 공용 메서드가 중단되면 해당 다른 메서드도 재정의 할 수 있습니다. 개인 방법을 위반하면 ....?
Kim

5
공용 메서드를 재정 의하여 발생하는 불쾌한 놀라움은 코드 냄새 자체입니다. 실제로 코드 악취.
래리 콜먼

Kim : 메소드가 공용 인 경우 다른 클래스도 해당 메소드를 호출한다고 가정해야합니다.
user281377

@Larry : 맞아요! 공개 메소드를 호출하는 개인 메소드 (일반적으로 구현 특정 가정이 포함됨)는 공개 메소드를 대체하면 문제가 발생할 가능성이 높습니다.
Kim

5

나는 우리가 성기를 할 수 있다고 생각하지 않습니다.

그것은 모두 상황에 따라 크게 좌우됩니다.

예를 들어 다른 클래스에서 사용하는 클래스의 공용 유틸리티 메소드와 동일한 클래스의 일부 개인 메소드가있을 수 있습니다.


5

아니요.이 경우 다른 조치를 취해야합니까? 비공개 메소드를 공개 또는 공개 메소드로 설정 하시겠습니까? 공개 메소드에서 개인 메소드로 코드를 복사하여 붙여 넣습니까?


또는 공개 메소드가 다른 개인 메소드에 의해 호출되는 (새로운) 개인 메소드에 위임하도록하십시오. 그러나 왜 귀찮게합니까?
Lawrence Dol

4

아니 , 여기 나쁜 냄새가 없습니다.

List로 큐의 인터페이스를 구현하면 큐를 쉽게 구현하기 위해 적절한 List 함수를 호출하는 것이 나쁜 냄새입니까?

무언가가 있고 그것을 래퍼와 같은 다른 것으로 바꾸고 싶다면 나쁜 냄새가 나지 않습니다. 함수 수준에서 디자인 패턴이 적용된 코드 재사용 가능성 (함수는 객체입니까?)


2

나는 이것이 오래된 게시물이라는 것을 알고 있지만, 나는 직장에서 토론하고있는 것입니다. 나는 이것을 코드 냄새라고 생각하고 왜 당신이 이것을하고 싶어하는지 이해할 수 없다. 개인 메소드가 공개 메소드를 호출해야하는 경우, 공개 메소드의 컨텐츠를 개인 메소드로 가져 와서 두 메소드가 모두 호출 할 수 있어야합니다. 왜?

  1. 공개 메소드에는 내부에서 코드를 실행 한 후 필요하지 않은 테스트가 포함될 수 있습니다. 예를 들어 UserObj를 수신하고 사용자 권한을 테스트하려고 할 수 있습니다.

  2. 공개 호출 후 스레딩을 사용하는 경우 객체를 잠그는 요구 사항이있을 수 있으므로 내부적으로 공개 메소드를 다시 호출하고 싶지 않습니다.

  3. 내 의견으로는 순환 오류와 무한 루프 및 mem out 예외가 발생할 가능성이 큽니다.

  4. 평범하고 간단하게 나쁜 디자인과 "게으른". 공개 방법은 외부 세계에 대한 액세스를 제공합니다. 이미 안에있을 때 밖으로 걸어 갈 이유가 없습니다.


1
기존의 공개 메소드가 다른 많은 클래스에 의해 호출되면 어떻게됩니까? 비공개로 설정하면 문제가 해결됩니다. 공용 클래스는이 클래스뿐만 아니라 다른 이유로 다른 클래스에 의해 호출됩니다. 공용 메소드가 존재하는 이유.
Michael Durrant

나는 '공개 방법의 내용을 개인 방법으로 가져와야한다 ...'고 말했다. 동일한 기능을 재사용해야하는 다른 개인용 메소드도 마찬가지입니다.
Mark Graham

따라서 다른 방법으로 다른 방법을 추가하고 있습니다. 왜냐하면 이것을 "코드 냄새"라고 선언했기 때문입니다. 무의미한 방법은 코드 냄새가 심합니다.
gnasher729

죄송하지만 위의 몇 가지 이유 만 열거하지 않았습니다. 내가 작성한 많은 코드는 비즈니스 시스템 용이며 많은 클래스는 역할에 따라 사용자로 제한됩니다. 많은 공개 메소드는 사용자 권한 및 매개 변수를 테스트합니다. 왜 지구상에서 동일한 공용 메소드를 다시 호출하여 기능을 재사용하고 사용자 권한을 다시 테스트하고 싶습니까?
Mark Graham

나는 내 인생에서 결코 개인의 방법으로 공개적인 방법을 호출 할 필요가 없었습니다. 그것은 나에게 매우 잘못 보이고 느낀다. 나는 대부분의 사람들이 괜찮다고 생각하는 것에 정말 놀랐습니다.
Trap

2

그 반대를 상상해보십시오. 개인 메서드에 있고 공용 메서드의 기능이 필요합니다 . 개인 메서드에서 해당 공용 메서드를 호출 할 수없는 경우 당신은 무엇을 하시겠습니까?

  • 중복 개인 메소드를 작성 하시겠습니까? 아니
  • 사건에 대한 특별한 공개 방법을 만드시겠습니까? 아니
  • 공개 메소드를 호출 할 수있는 특별한 개인 메소드를 호출 하시겠습니까? 아니
  • 이것을 할 수있는 일종의 슈퍼? 아니

대답은 공개 메소드의 기능을 원할 때이 클래스의 메소드 또는 다른 클래스에서 해당 메소드를 호출 할 수 있어야한다는 것입니다.


1

내 코드에서 종종 게으른로드 게터를 생성합니다. 즉, 처음 요청했을 때 객체가 초기화되고 이후에 동일한 인스턴스화 된 객체를 재사용합니다. 그러나 지연로드를 사용하여 인스턴스화 된 오브젝트는 특정 지점에서 반드시 인스턴스화 될 필요는 없음을 의미합니다. 객체가 이미 인스턴스화되었거나 다른 메소드 내에서 동일한 지연로드 코드를 반복한다는 것을 알기 위해 호출 시퀀스 주위에 내 머리를 감싸기보다는 객체가 필요할 때마다 지연 로더를 호출합니다.

현명한 방법으로 공용 메소드를 사용할 수있는 것처럼 잘못 사용할 수도 있습니다. 예를 들어 다른 개인용 메서드를 호출하기 전에 매개 변수를 처리하는 공용 메서드가 있습니다. 동일한 매개 변수를 가지고 있기 때문에 단순히 공개 메소드를 자연스럽게 호출하는 것은 실수입니다. 실수는 미묘하지만 다른 무엇보다 설계 오류이므로 공용 메소드의 매개 변수가 아닌 내부 메소드의 매개 변수로 관리하는 법을 배워야합니다.

따라서 귀하의 질문에 대답하기 위해 올바르게 사용하면 나쁜 코드가 아닙니다.


1

스스로에게 물어보아야 할 질문은 왜 수업에 고객의 수업과 같은 필요가 있습니까? 일반적으로 클래스는 클라이언트와 요구가 매우 다릅니다. 예, 이것은 귀하가

(a) 사적인 것이어야하는 것을 공개적으로 노출시키는 것; 또는

(b) 반의 행동이 충분히 좁지 않다 (단일 책임 원칙을 생각하라).

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