정적 메소드를 통해 객체를 전달하는 것이 유리한 이유는 무엇입니까?


9

정적 메소드를 사용하고 오브젝트에 대한 메소드를 호출하는 대신 오브젝트에 대한 참조를 매개 변수로 전달하는 이점이있는 이유는 무엇입니까?

내가 의미하는 바를 명확히하기 위해 다음 클래스를 고려하십시오.

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public void incrementValue() {
        someValue++;
    }
}

정적 메소드를 사용한이 대체 구현과 비교하면 다음과 같습니다.

public class SomeClass {
    private double someValue;

    public SomeClass() {
        // Some constructor in which someValue is set
    }

    public static void incrementValue(SomeClass obj) {
        obj.someValue++;
    }
}

내 질문은이 수업에만 국한되지 않습니다. 메소드에서 객체를 호출하는 대신 객체를 전달하는 지점은 제가 관심있는 것입니다. 이것이 유리합니까? 그렇다면 왜 그렇습니까?


1
그것은 똑같은 일을하는 두 가지 방법으로 코드 냄새처럼 느껴집니다. 정적 메서드가 단순히 다른 메서드에 위임 된 경우 쓸모는 없지만 "나쁜"느낌은 아닙니다.
Nathan Merrill

13
@NathanMerrill 당신이 요점을 놓치고 있다고 생각합니다. 그는 첫 번째 방법 대신 두 번째 방법을 만들고 사용하는 것이 바람직한 상황이 있는지 묻습니다 .

@Mego 예제에 제공된 방법뿐만 아니라; 이 경우 내가 부탁 해요 어느 순간 정적 메소드를 사용하여 객체의 메소드를 호출하는 것보다 더 나은 물체를 통과 할 때?
Addison Crump

아마도 당신은 자바를 특별히 요구하고 있습니까?
enderland

3
이 질문은 객체 지향 코드가 어떤 종류의 최적이라고 암묵적으로 가정합니다. 보다 절차 적이거나 기능적인 접근 방식은 자연스럽게 정적 메소드를 사용하게됩니다. 정적 메소드와 인스턴스 메소드 사이의 기능을 복제하는 것은 어리석은 일입니다. 나는 이것이 단지 예일 뿐이고 당신이 이야기하고있는 실제 코드는 정적 일 뿐이다.
jpmc26

답변:


34

간단한 예 : 전달 된 인스턴스가 합법적으로 null 일 수 있으며이를 (사소하지 않은) 처리 방법으로 통합하려는 경우.


1
예 : C #에서 String.Compare 비교 (Java에 비슷한 것이 있다고 생각합니다)
edc65

Objects.equals () 및 Objects.compare ()는 Java의 예이지만 원래 클래스에는 없습니다. 적어도 자바 표준 라이브러리에서는 객체 같은에서 인스턴스 메서드, 그러나 객체의 정적 메소드가하는 것이 일반적 S 클래스.
daboross

20

귀하의 예에서 인스턴스 메소드는 확실한 승자입니다.

일반적인 경우 정적 메서드가 적절한 몇 가지 이유를 생각할 수 있습니다.

  • 로직과 데이터를 분리하는 것이 합리적이므로 정적 메소드를 다른 클래스에 배치하려고합니다 (참고 : 예제는 그 중 하나가 아닙니다).

  • 둘 이상의 객체를 전달하고 있으며 동일한 중요성을 강조하려고합니다.

  • null 유효한 값입니다 (사용자 9000에서 설명한대로).


5

객체의 상태를 정적 메소드가 아닌 인스턴스 메소드 로 변경하는 메소드를 포함하는 것이 좋습니다 .

그러나 pure특정 유효성 검사 규칙에 따라 개체를 인스턴스화해야 할 때처럼 메서드 인 정적 메서드의 예제를 찾아서 개체를 입력으로 사용합니다. 예를 들어 .NET 에는 DateTime.TryParse(String s, DateTime d)개체의 유효성을 검사하고 인스턴스화하는 방법 이 있습니다. 그러나 매개 변수 DateTime d는 명시 적으로로 표시됩니다 out.

또 다른 경우는 객체를 비교하고 비교 결과의 부울 / 정수 값이 아닌 반환 값으로 원하는 객체를 얻으려는 경우입니다 (예 :) Team.GetHigherScorer(teamA, teamB).IncreaseRanking(). 이것은 다음보다 깨끗합니다.

int compareResult = teamA.compareScoreWith(teamB);
if (compareResult == 1)
    teamA.IncreaseRanking();
else if (compareResult == -1) 
    teamB.IncreaseRanking();

(간단하게하기 위해 사례를 "인출"한 채로 둡니다).


1
하나는 "전체 개체"를 전달하지 않습니다. 아주 적은 양의 데이터가 전달되는 메모리의 위치로 참조를 전달합니다. 성능에 미치는 영향은 확실하지 않지만 그럼에도 불구하고 "out"표시는 무엇을 의미합니까?
Addison Crump

1
나는 진술에서 '전체'라는 단어를 떨어 뜨렸다. 혼란 스러웠다. 나는 성능이나 규모를 의도하지 않았으며, 대답은 순전히 프로그래밍 관행에 기반합니다. 어쨌든 매개 변수 수정 자로 사용 out되는 .Net키워드입니다. 매개 변수가 참조로 전달됨을 나타냅니다. 자세한 내용은 msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
wonderbell

4
첫 번째 문장은 단순히 잘못되었습니다. 우리가 가지고 있다면 class C { int x; static void M() { M은 완벽하게 접근 할 수 있습니다 x. 예를 들어 int y = (new C()).x;합법적입니다.
Eric Lippert

@EricLippert :) 나는 당신이 무슨 뜻인지 알 것입니다. 마스터가 라인 사이를 읽는 방법이 놀랍습니다. 그 문장을 편집해야 할 수도 있습니다. 명확히하기 위해 이와 같은 static void M() { this.x = 1; }것은 불가능합니다.
wonderbell

1
@wonderbell : 아니요, 당신이 무슨 뜻인지 몰랐습니다. 당신이 쓴 것을 알고있었습니다. 나는주의 this.x때문에하지 잘못 x액세스 할 수 있지만, 때문에 this않습니다 존재하지. 그것은 전혀 접근 의 문제가 아니라 존재 의 문제입니다 .
Eric Lippert

4

의존성 주입은 정적 메소드에 대한 호출을 수행하는 좋은 이유입니다. 구체적인 구현에 SomeClass상속 체인이 있거나 다른 클래스의 구현 이라고 가정합니다 . 객체의 모의를 사용하여 테스트 목적으로 메소드가 전달 된 방식을 수행하는지 확인한 후 해당 상태를보고 할 수 있습니다.

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