객체 메서드 내에서 객체 속성에 어떻게 액세스합니까?[닫은]

StackOverflow https://stackoverflow.com/questions/126

  •  08-06-2019
  •  | 
  •  

문제

getter/setter 메서드가 아닌 개체 메서드 내에서 개체의 속성에 액세스하는 "순수주의" 또는 "올바른" 방법은 무엇입니까?

나는 객체 외부에서 getter/setter를 사용해야 한다는 것을 알고 있지만 내부에서는 다음을 수행합니다.

자바:

String property = this.property;

PHP:

$property = $this->property;

아니면 다음과 같이 하시겠습니까?

자바:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

내 Java가 약간 부족하더라도 용서하세요. Java로 프로그래밍한 지 1년이 지났습니다.

편집하다:

사람들은 내가 개인 또는 보호 변수/속성에 대해서만 이야기하고 있다고 가정하는 것 같습니다.OO를 배웠을 때 저는 모든 단일 속성이 공개인 경우에도 getter/setter를 사용하는 방법을 배웠습니다(실제로는 어떤 변수/속성도 공개하지 말라는 지시를 받았습니다).그래서 나는 처음부터 잘못된 가정에서 시작할 수도 있습니다.이 질문에 대답하는 사람들은 아마도 공용 자산이 있어야 하며 여기에는 getter 및 setter가 필요하지 않다고 말하는 것 같습니다. 이는 제가 배운 것과 제가 말한 내용에 어긋나는 것입니다. 잘.그것은 아마도 다른 질문에 대한 좋은 주제 일 것입니다 ...

도움이 되었습니까?

해결책

이것은 종교적 전쟁 가능성이 있지만 getter/setter를 사용하는 경우 내부적으로도 사용해야 하는 것 같습니다. 둘 다 사용하면 향후 유지 관리 문제가 발생할 수 있습니다(예:누군가가 setter에 코드를 추가합니다. 필요 해당 속성이 설정될 때마다 실행되며 해당 설정자가 호출되지 않고 속성이 내부적으로 설정됩니다.

다른 팁

개인적으로는 꾸준함을 유지하는 것이 중요하다고 생각합니다.getter와 setter가 있으면 이를 사용하세요.필드에 직접 액세스하는 유일한 경우는 접근자에게 많은 오버헤드가 있을 때입니다.코드를 불필요하게 부풀리는 것처럼 느껴질 수도 있지만 앞으로는 확실히 많은 골칫거리를 줄일 수 있습니다.전형적인 예:

나중에 해당 필드가 작동하는 방식을 변경하고 싶을 수도 있습니다.즉석에서 계산해야 할 수도 있고 백업 저장소에 다른 유형을 사용하고 싶을 수도 있습니다.속성에 직접 액세스하는 경우 이와 같은 변경으로 인해 한 번에 엄청난 양의 코드가 손상될 수 있습니다.

나는 그 감정이 얼마나 만장일치인지에 상당히 놀랐습니다. getters 세터도 괜찮고 좋습니다.Allen Holub의 선동적인 기사를 제안합니다.게터와 세터는 악하다".물론 제목은 충격적이지만 저자는 타당한 지적을 하고 있습니다.

기본적으로 getters 그리고 setters 각각의 모든 비공개 필드에 대해 해당 필드를 공개만큼 좋게 만듭니다.이를 호출하는 모든 클래스에 파급 효과 없이 비공개 필드의 유형을 변경하는 것은 매우 어려울 것입니다. getter.

더욱이, 엄격한 OO의 관점에서 볼 때, 객체는 (희망적으로) 단일 책임에 해당하는 메시지(메서드)에 응답해야 합니다.대다수의 getters 그리고 setters 구성 객체에 대해 이해가 되지 않습니다.Pen.dispenseInkOnto(Surface) 나한테는 그보다 더 의미가 있어 Pen.getColor().

Getter 및 Setter는 또한 클래스 사용자가 객체에 일부 데이터를 요청하고 계산을 수행한 다음 객체에 다른 값을 설정하도록 권장합니다. 이는 절차적 프로그래밍으로 더 잘 알려져 있습니다.처음에 하려고 했던 일을 객체에게 간단히 지시하는 것이 더 나을 것입니다.로도 알려져 있습니다. 정보 전문가 관용구.

그러나 Getter와 Setter는 레이어 경계(UI, 지속성 등)에서 필요악입니다.C++의 friend 키워드, Java의 패키지 보호 액세스, .NET의 내부 액세스 및 친구 클래스 패턴 가시성을 줄이는 데 도움이 될 수 있습니다. getters 필요한 사람에게만 설정자를 제공합니다.

해당 자산이 어떻게 사용되는지에 따라 다릅니다.예를 들어, 이름 속성이 있는 학생 개체가 있다고 가정해 보겠습니다.아직 검색되지 않은 경우 Get 메서드를 사용하여 데이터베이스에서 이름을 가져올 수 있습니다.이렇게 하면 데이터베이스에 대한 불필요한 호출을 줄일 수 있습니다.

이제 이름이 호출된 횟수를 계산하는 개인 정수 카운터가 개체에 있다고 가정해 보겠습니다.잘못된 개수가 생성되므로 개체 내부에서 Get 메서드를 사용하지 않는 것이 좋습니다.

PHP는 매직 메소드를 포함하여 이를 처리하는 다양한 방법을 제공합니다. __get 그리고 __set, 그러나 나는 명시적인 getter와 setter를 선호합니다.이유는 다음과 같습니다.

  1. 유효성 검사는 setter(및 해당 문제에 대한 getter)에 배치될 수 있습니다.
  2. Intellisense는 명시적 메서드와 함께 작동합니다.
  3. 속성이 읽기 전용인지, 쓰기 전용인지, 읽기-쓰기인지는 의심할 여지가 없습니다.
  4. 가상 속성(예: 계산된 값) 검색은 일반 속성과 동일하게 보입니다.
  5. 실제로 어디에도 정의되지 않은 객체 속성을 쉽게 설정할 수 있으며, 이는 문서화되지 않습니다.

내가 여기서 너무 지나치게 되는 걸까?

아마도 ;)

또 다른 접근 방식은 실제로 가져오기(캐싱/db/etc)를 수행하기 위해 개인/보호 방법과 개수를 증가시키는 공용 래퍼를 활용하는 것입니다.

PHP:

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

그런 다음 객체 자체 내에서 다음을 수행합니다.

PHP:

$name = $this->_getName();

이렇게 하면 첫 번째 인수를 다른 용도로 계속 사용할 수 있습니다(여기서 캐시된 데이터를 사용할지 여부에 대한 플래그 전송 등).

여기서 요점을 놓치고 있는 것 같습니다. 해당 객체의 속성에 액세스하기 위해 객체 내부의 getter를 사용하는 이유는 무엇입니까?

결론적으로 getter는 getter를 호출해야 하며, getter는 getter를 호출해야 합니다.

따라서 객체 메서드 내에서 속성에 직접 액세스한다고 말하고 싶습니다. 특히 해당 객체에서 다른 메서드를 호출하는 것(어차피 속성에 직접 액세스한 다음 반환함)은 무의미하고 낭비적인 연습일 뿐입니다(또는 제가 질문을 오해한 것일까요?) ).

"순수주의자"가 "대부분의 캡슐화"를 의미하는 경우 일반적으로 모든 필드를 비공개로 선언한 다음 클래스 자체 내에서 this.field를 사용하지만 하위 클래스를 포함한 다른 모든 클래스는 getter를 사용하여 인스턴스 상태에 액세스합니다.

객체 내에서도 접근자 메서드를 사용하는 것이 더 낫다고 말하고 싶습니다.즉시 내 마음에 떠오르는 요점은 다음과 같습니다.

1) 객체 외부에서 이루어진 접근과의 일관성을 유지하기 위해 이루어져야 합니다.

2) 경우에 따라 이러한 접근자 메서드는 필드에 액세스하는 것 이상의 작업을 수행할 수 있습니다.추가 처리를 수행할 수도 있습니다(드물지만).이 경우 필드에 직접 액세스하면 추가 처리가 누락되고 해당 액세스 중에 이 처리가 항상 수행되면 프로그램이 잘못될 수 있습니다.

순수한 OO 방식은 두 가지를 모두 피하고 다음을 따르는 것입니다. 데메테르의 법칙 을 사용하여 묻지 말고 말하라 접근하다.

객체의 속성 값을 얻는 대신, 단단히 커플 두 클래스에서는 객체를 매개변수로 사용합니다.

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

속성이 기본 유형인 경우(예:int, 액세스 방법을 사용하고 프로그래밍 도메인이 아닌 문제 도메인에 대해 이름을 지정합니다.

  doSomethingWithProperty( this.daysPerWeek() ) ;

이를 통해 캡슐화와 사후 조건 또는 종속 불변성을 유지할 수 있습니다.사전 조건이나 종속 불변성을 유지하기 위해 setter 메서드를 사용할 수도 있지만, setter라는 이름을 지정하는 함정에 빠지지 말고 관용구를 사용할 때 이름 지정에 대해 Hollywood 원리로 돌아가세요.

나는 setter/getter를 사용하면 내 코드를 더 쉽게 읽을 수 있다는 것을 알았습니다.또한 다른 클래스가 메서드를 사용할 때 제공되는 컨트롤과 속성이 저장할 데이터를 변경할 때 제공되는 컨트롤도 마음에 듭니다.

공개 또는 보호 속성이 있는 비공개 필드입니다.값에 대한 액세스는 속성을 거쳐야 하며, 해당 값이 메서드에서 두 번 이상 사용되는 경우 로컬 변수에 복사되어야 합니다.응용 프로그램의 나머지 부분을 완전히 조정하고, 조정하고, 관련 속성을 통해 값에 액세스하는 것이 병목 현상이 되는 위치에 최적화된 경우에만(그리고 그런 일은 결코 일어나지 않을 것입니다. 보장합니다) 시작해야 합니다. 속성 이외의 다른 것이 지원 변수에 직접 닿도록 하는 것을 고려하십시오.

.NET 개발자는 디자인 타임에 지원 변수를 볼 수도 없기 때문에 자동 속성을 사용하여 이를 적용할 수 있습니다.

속성을 편집하지 않으면 get_property() 다른 객체 내부의 MySQLi 객체와 같은 특별한 경우가 아닌 한 공개 메소드를 사용합니다. 이 경우 속성을 공개하고 다음과 같이 참조하겠습니다. $obj->object_property.

객체 내부에는 항상 $this->property가 있습니다.

때에 따라 다르지.다른 무엇보다 스타일 문제이며 엄격한 규칙은 없습니다.

나는 독학자이기 때문에 틀릴 수 있지만 Java 클래스의 공용 속성을 절대 사용하지 않습니다. 이 속성은 항상 개인용이거나 보호되어 있으므로 외부 코드는 getter/setter에 의해 액세스되어야 합니다.유지 관리/수정 목적으로 사용하는 것이 더 좋습니다.그리고 내부 클래스 코드의 경우 ...getter 메서드가 사소한 경우에는 속성을 직접 사용하지만 원하는 경우 이벤트를 실행하는 코드를 쉽게 추가할 수 있기 때문에 항상 setter 메서드를 사용합니다.

글쎄요, C# 3.0 속성의 기본 구현을 사용하면 결정이 자동으로 이루어지는 것 같습니다.(아마도 개인용) 속성 설정자를 사용하여 속성을 설정해야 합니다.

저는 개인적으로 비공개 멤버를 사용하지 않을 경우 초기화할 때나 캐싱/지연 로딩이 관련된 경우와 같이 객체가 바람직하지 않은 상태에 빠지게 할 때만 사용합니다.

나는 대답을 좋아한다 cmcculloh, 하지만 가장 정확한 답변은 다음과 같습니다. 그렉 헐먼.getgo에서 사용하기 시작했거나 작업에 익숙해진 경우 항상 getter/setter를 사용하십시오.

여담이지만, 저는 개인적으로 getter/setter를 사용하면 나중에 코드를 더 쉽게 읽고 디버깅할 수 있다고 생각합니다.

일부 의견에 명시된 바와 같이 :때로는 그래야 할 때도 있고, 때로는 하지 말아야 할 때도 있습니다.개인 변수의 가장 큰 장점은 무언가를 변경할 때 해당 변수가 사용되는 모든 위치를 볼 수 있다는 것입니다.getter/setter가 필요한 작업을 수행하는 경우 이를 사용하세요.중요하지 않다면 결정하세요.

getter/setter를 사용하고 누군가가 getter/setter를 변경하는 경우 getter 및 setter가 내부적으로 사용되는 모든 위치를 분석하여 문제가 있는지 확인해야 하는 반대의 경우가 발생할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top