source

오브젝트 메서드 내에서 오브젝트 속성에 액세스하려면 어떻게 해야 합니까?

lovecheck 2023. 1. 2. 22:41
반응형

오브젝트 메서드 내에서 오브젝트 속성에 액세스하려면 어떻게 해야 합니까?

getter/setter 메서드가 아닌 오브젝트 메서드 내에서 오브젝트의 속성에 액세스하기 위한 "purist" 또는 "올바른" 방법은 무엇입니까?

오브젝트 외부에서 getter/setter를 사용해야 한다는 것을 알고 있습니다만, 내부에서는 다음과 같이 합니다.

자바:

String property = this.property;

PHP:

$property = $this->property;

아니면 어떻게 하시겠습니까?

자바:

String property = this.getProperty();

PHP:

$property = $this->getProperty();

자바가 좀 이상해도 자바에서 프로그램한 지 1년이 지났는데...

편집:

개인 또는 보호된 변수/속성에 대해서만 말하는 것으로 추측되는 것 같습니다.저는 OO를 배울 때, 공개되어 있어도 모든 자산에 대해 getters/setters를 사용하도록 배웠습니다(그리고 실제로 변수/속성을 공개하지 말라고 들었습니다).그래서 처음부터 잘못된 추측에서 출발할 수도 있습니다.이 질문에 대답하는 사람들은 공공재산을 가져야 한다고 말하고 있는 것 같습니다.그것은 제가 배운 것과 제가 말한 것에 반하는 것입니다만, 그것도 논의될 필요가 있을지도 모릅니다.다른 질문으로 넘어가면 좋을 것 같은데...

이것은 종교적인 전쟁의 가능성이 있지만, 만약 당신이 getter/setter를 사용하고 있다면, 당신은 내부적으로도 그것을 사용해야 할 것 같습니다.- 두 가지를 모두 사용하면 향후 유지보수에 문제가 생깁니다(예를 들어, 누군가 속성을 설정할 때마다 실행해야 하는 설정기에 코드를 추가하고, 그 설정기가 호출될 때마다 그 속성을 내부적으로 설정합니다).

개인적으로, 저는 일관성을 유지하는 것이 중요하다고 생각합니다.getter와 setter가 있다면 그것들을 사용하세요.직접 필드에 액세스 할 수 있는 유일한 시간은 액세스 장치에 오버헤드가 많은 경우입니다.불필요하게 코드를 부풀리고 있는 것처럼 느껴질 수도 있지만, 장래의 큰 골칫거리를 확실히 경감할 수 있습니다.전형적인 예:

나중에 필드의 작동 방식을 변경할 수 있습니다.즉석에서 계산해야 할 수도 있고, 백업 스토어에 다른 유형을 사용할 수도 있습니다.만약 당신이 직접 속성에 접속한다면, 그와 같은 변경은 한 번에 엄청난 양의 코드를 깨트릴 수 있습니다.

getters세터도 괜찮고 좋아요.나는 Allen Holub의 선동적인 기사 "Getters And Setters Are Evil"을 제안한다.물론 충격적 가치의 제목이지만 저자는 타당한 논점을 내세운다.

「 」가 경우는, 「 」입니다.getters ★★★★★★★★★★★★★★★★★」setters모든 개인 분야를 공개하는 것처럼 좋은 분야로 만들고 있습니다.하는 것은 어려운 은 파급 입니다.이러한 명령어를 호출하는 모든 클래스에 파급 효과가 없습니다.getter.

또한, 엄밀하게는 OO의 관점에서 개체는 단일 책임에 해당하는 메시지(방법)에 응답해야 한다.의의 the의 getters ★★★★★★★★★★★★★★★★★」setters목적을 하지 못하다.Pen.dispenseInkOnto(Surface)엔 '하다'보다 ''가 더 말이 된다.Pen.getColor().

또한 getters와 setters는 클래스 사용자에게 오브젝트에 데이터를 요청하고 계산을 수행한 다음 프로시저 프로그래밍으로 더 잘 알려진 오브젝트에 다른 값을 설정하도록 권장합니다.정보 전문가용어로도 알려져 있는, 애초에 대상에게 자신이 가고 있던 일을 하라고 간단히 말하는 것이 더 나을 것입니다.

그러나 getter와 setter는 UI, 지속성 등의 계층 경계에 있는 필요악입니다.C++의 friend 키워드, Java의 패키지 보호 액세스 등 클래스의 내부 액세스 제한.NET의 내부 액세스와 Friend Class Pattern을 통해 다음과 같은 정보를 쉽게 확인할 수 있습니다.getters이치노

그것은 그 부동산이 어떻게 사용되는지에 달려있다.예를 들어 이름 특성이 있는 학생 객체가 있다고 가정합니다.아직 검색되지 않은 경우, Get 메서드를 사용하여 데이터베이스에서 이름을 가져올 수 있습니다.이렇게 하면 데이터베이스에 대한 불필요한 콜을 줄일 수 있습니다.

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

의 방법인 PHP를 합니다.__get ★★★★★★★★★★★★★★★★★」__set하지만 저는 명시적인 게터나 세터를 선호합니다.을 사용하다

  1. 검증은 세터(및 그 건에 대해서는 게터)에 배치할 수 있습니다.
  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();

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

요점을 놓쳤나 보군, 왜 오브젝트 내부에 있는 게터를 사용하여 오브젝트의 속성에 접근하려는 거지?

결론부터 말하면, 게터는 게터를 호출해야 하고, 게터는 게터를 호출해야 합니다.

따라서 오브젝트 메서드 내에서는 오브젝트 내의 다른 메서드를 호출하는 것(어차피 오브젝트에 직접 액세스한 후 반환하는 것)은 무의미하고 낭비적인 연습일 뿐입니다(혹은 질문을 잘못 이해한 경우).

오브젝트 내에서도 액세스 방식을 사용하는 것이 좋습니다.바로 떠오르는 요점은 다음과 같습니다.

  1. 오브젝트 외부에서 이루어지는 액세스와의 일관성을 유지하기 위해 이 작업을 수행해야 합니다.

  2. 경우에 따라서는, 이러한 액세스 방식에서는, 필드에의 액세스 뿐만이 아니라, 몇개의 추가 처리를 실시하는 경우가 있습니다(다만, 이것은 드문 경우입니다).이 경우 필드에 직접 액세스하면 추가 처리가 누락되고 이러한 액세스 중에 이 처리가 항상 수행되어야 하는 경우 프로그램이 잘못될 수 있습니다.

"purist"에서 "most encapsulation"을 의미하는 경우, 일반적으로 모든 필드를 private로 선언하고 클래스 자체에서 "this.field"를 사용합니다.서브클래스를 포함한 다른 클래스의 경우 getters를 사용하여 인스턴스 상태에 액세스합니다.

그 질문은 의견 기반 답변을 요구하지 않는다.이것은 높은 응집력, 낮은 결합력 및 솔리드 원칙에서 수십 년 동안 컴퓨터 과학에 의해 잘 다뤄진 주제입니다.

순수주의자(정확하게 읽음)의 OO 방법은 결합을 최소화하고 응집력을 극대화하는 것입니다.따라서 둘 다 피해야 하며, 디메터의 법칙에 따라 Tell Don't Ask 접근 방식을 사용해야 합니다.

두 클래스를 긴밀하게 결합하는 개체 속성 값을 가져오는 대신 개체를 매개 변수로 사용합니다.

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

속성이 네이티브 유형(예: int)인 경우 액세스 방법을 사용하고 프로그래밍 도메인이 아닌 문제 도메인의 이름을 지정합니다.

  doSomethingWithProperty( this.daysPerWeek() ) ;

이를 통해 캡슐화 및 사후 조건 또는 종속 불변수를 유지할 수 있습니다.setter 메서드를 사용하여 사전 조건이나 종속 불변수를 유지할 수도 있지만, setter 이름을 붙이는 함정에 빠지지 말고 Hollywood Principle로 돌아가 관용어를 사용할 때 이름을 붙입니다.

세터/게터를 사용하면 코드를 쉽게 읽을 수 있습니다.또한 다른 클래스에서 메서드를 사용할 때 제공되는 제어 기능과 데이터를 변경하면 속성이 저장되는 제어 기능도 마음에 듭니다.

공용 또는 보호된 속성이 있는 개인 필드.값에 대한 액세스는 속성을 통과해야 하며 메서드에서 두 번 이상 사용되는 경우 로컬 변수에 복사되어야 합니다.어플리케이션의 나머지 부분을 완전히 조정, 변경 및 최적화하여 할당된 속성을 통해 값에 액세스하는 것이 병목현상이 된 경우(그리고 그런 일은 절대 일어나지 않을 것입니다)에는, 속성 이외의 다른 것은 그 뒷받침에 영향을 주는 것을 검토하는 것조차 시작해야 합니다.직접 변수를 지정합니다.

.NET 개발자는 자동 속성을 사용하여 이를 적용할 수 있습니다. 설계 시 백업 변수조차 볼 수 없기 때문입니다.

사정에 따라 다르겠지.그것은 다른 무엇보다 스타일 문제이고, 엄격한 규칙은 없다.

제가 자동 응답이기 때문에 틀릴 수도 있지만, 저는 Java 클래스의 공용 속성을 절대 사용하지 않습니다.이러한 속성은 항상 비공개이거나 보호되기 때문에 외부 코드는 getters/setters에 의해 액세스해야 합니다.유지 보수/변경을 위해 더 좋습니다.그리고 내부 클래스 코드는...getter 방식이 사소한 경우에는 직접 속성을 사용하지만, 원할 경우 이벤트에 코드를 쉽게 추가할 수 있기 때문에 항상 setter 방식을 사용합니다.

속성을 편집하지 않으면 공용 메서드를 사용합니다.get_property()다른 오브젝트 내의 MySQLi 오브젝트와 같은 특별한 경우가 아니라면 이 경우 해당 속성을 공개하고 다음과 같이 참조합니다.$obj->object_property.

오브젝트 내부에는 항상 $this->속성이 있습니다.

C# 3.0 속성의 디폴트 실장에서는 사용자가 결정할 수 있습니다.프로퍼티 세터를 사용하여 속성을 설정해야 합니다.

개인적으로는 Private member-behind를 사용하지 않으면 초기화 시 또는 캐시/lazy loading과 같은 오브젝트가 바람직하지 않은 상태가 될 경우에만 사용합니다.

는 cmcculloh의 답을 좋아하지만, 가장 정확한 답은 Greg Hurlman의 대답인 것 같다.getter/setter를 처음부터 사용하기 시작했거나 사용하는 데 익숙하다면 항상 getter/setter를 사용하십시오.

참고로 개인적으로 getter/setter를 사용하면 코드를 읽고 나중에 디버깅할 수 있습니다.

코멘트 중 일부에 기재된 바와 같이:때로는 그래야 하고, 때로는 그래야 하지 말아야 해요.개인 변수의 가장 큰 장점은 무언가를 변경할 때 사용되는 모든 위치를 볼 수 있다는 것입니다.getter/setter가 필요한 작업을 수행하는 경우 사용합니다.상관없다면 네가 결정해.

반대로 getter/setter를 사용할 경우 getter/setter를 변경할 경우 getter와 setter가 내부적으로 사용되는 모든 장소를 분석하여 문제가 없는지 확인해야 합니다.

언급URL : https://stackoverflow.com/questions/126/how-would-you-access-object-properties-from-within-an-object-method

반응형