개인 변수가 필요한 이유는 무엇입니까?


210

클래스에 개인 변수가 필요한 이유는 무엇입니까?

내가 읽은 프로그래밍에 관한 모든 책은 이것이 개인 변수라고 말합니다.

이 설명의 문구는 항상 우리가 직업에 대한 신뢰의 위기가있는 것처럼 보였다. 설명은 항상 다른 프로그래머가 코드를 망치는 것처럼 들립니다. 그러나 개인 변수가없는 많은 프로그래밍 언어가 있습니다.

  1. 개인 변수는 무엇을 방지하는 데 도움이됩니까?

  2. 특정 재산이 사유인지 아닌지를 어떻게 결정합니까? 기본적으로 모든 필드가 비공개이어야한다면 왜 클래스에 공개 데이터 멤버가 있습니까?

  3. 어떤 상황에서 변수를 공개해야합니까?


9
귀하의 질문은 언어에 구애받지 않는 것처럼 들리지만 java 및 c ++로 태그를 지정했습니다. 두 언어 이외의 관점에서 관심이 있다면 그렇게 말해야합니다.
James

8
레코드의 경우 개인 메소드를 작성해도 "보안"이 증가하지는 않습니다. 애플리케이션의 다른 부분은 여전히 ​​리플렉션을 사용하여 개인 멤버에 액세스 할 수 있습니다.
kba

3
개인 변수와 공용 변수의 사용법과 차이점, 그리고 변수가있는 이유는 일반적인 객체 지향 원칙의 맥락에서만 이해할 수 있습니다. 별도로 이해할 수 없습니다. 아마도 그 관점에서보아야 할 것입니다.
Nazar Merza


3
자동차에서 안전 벨트를 사용하는 사람을 잡는 경우 운전 면허증을 빼야합니다.
gnasher729

답변:


307

그것은 신뢰의 문제가 아니라 복잡성을 관리하는 문제입니다.

클래스 외부에서 공개 멤버에 액세스 할 수 있습니다. 실질적인 고려 사항은 "잠재적으로 어디든"을 의미합니다. 퍼블릭 필드에 문제가 발생하면 범인은 어디에나있을 수 있으므로 버그를 추적하려면 많은 코드를 봐야 할 수도 있습니다.

대조적으로 개인 멤버는 동일한 클래스 내에서만 액세스 할 수 있으므로 문제가있는 경우 일반적으로 볼 소스 파일이 하나뿐입니다. 프로젝트에 백만 줄의 코드가 있지만 클래스가 작게 유지되면 버그 추적 노력을 1000 배 줄일 수 있습니다.

또 다른 장점은 '커플 링'개념과 관련이 있습니다. 공개 멤버 m클래스의 A다른 클래스에 의해 사용되는 B종속성을 소개 : 당신이 변경하는 경우 mA, 당신은 또한의 용도를 확인해야 mB. 더 나쁜 것은, 수업 중 어느 Am에서 사용 중인지 알려주지 않으므로 전체 코드베이스를 다시 검색해야합니다. 작성중인 라이브러리라면 외부 코드를 확인해야합니다.변경으로 인해 프로젝트가 중단되지 않습니다. 실제로 라이브러리는 아무리 고통 스럽더라도 가능한 한 오랫동안 원래의 메소드 서명을 고수 한 다음 주요 버전 업데이트를 통해 주요 변경 사항을 차단합니다. 반대로 비공개 멤버를 사용하면 종속성을 즉시 제외 할 수 있습니다. 외부에서 액세스 할 수 없으므로 모든 종속성이 클래스 내부에 포함됩니다.

이와 관련하여 "다른 프로그래머"에는 미래와 과거의 자아가 포함됩니다. 기회는 당신이 알고있는 지금 당신이 당신의 변수 Y와 함께이 일의 X를하지 말아야 할 것을,하지만 석 달 고객이 긴급하게 몇 가지 기능을 구현 할 필요가있는 길을 잊어 버린되어있어, 및 X 바꿈을하는 이유를 궁금해 모호한 방식으로 Y.

따라서 사물을 비공개로 만들어야 할 경우 기본적으로 모든 것을 비공개로 설정 한 다음 공개해야하는 부분 만 공개합니다. 비공개로할수록 더 좋습니다.


24
문제의 핵심을 이해하기위한 +1이지만, 자주 사용되는 변수가 비공개로 유지되도록 후프를 멈출 때 코드를 유지하기가 더 쉽다는 것을 개인적으로 알았습니다. ) 물론 오류가 미래에 올 수 있지만 부팅 (60)를 통해 선별하는 코드의 적은 선, 적은 변수와 함수의
제프리 스위니에게

48
현대 컴퓨팅의 성배는 복잡성을 줄이고 있습니다.

1
나는 항상 디버깅의 일부가 "무엇이 잘못되었는지"로 직접 나아가는 것이 아니라 "무슨 잘못이 아닌지"를 파악하고 남은 것에 대한 조사에 집중하는 과정을 밟고 싶다고 말하고 싶다. 컴파일러가 "사실 불가능한 일"을 정의하기 위해 전용 변수와 같은 도구를 지원하도록하면 시간을 절약 할 수 있습니다. 내가 잘못한 일이 발생하지 않았다는 것을 증명하는 드문 경우에만 개인 데이터를 덮어 쓰는 버퍼 오버런과 같이 더 무서운 가정을 파헤쳐 야합니다.
Cort Ammon

2
정확히 사람들이 "정보 숨기기"를 들으면 암호화 키, 데이터베이스 자격 증명 등과 같은 개인 변수를 사용해야한다고 생각합니다.
Wayne Werner

2
@AdamZerner 는 처음에 getter / setter를 갖는 것에 대해 "Tell, do n't ask"( martinfowler.com/bliki/TellDontAsk.html )를 참조하십시오. 그렇지 않으면 언제든지 값의 내부 표현을 자유롭게 변경할 수 있기 때문에 가능합니다. 당신이 원합니다. 언제나 그렇듯이 예외가 있습니다 ... (예 : DTO)
doubleYou

111

개인 변수는 사람들이 코드의 특정 부분에 의존하지 못하게합니다. 예를 들어, 일부 데이터 구조를 구현한다고 가정하십시오. 데이터 구조 사용자가 구현 방식에 신경 쓰지 말고 잘 정의 된 인터페이스를 통해 구현을 사용하기를 원합니다 . 그 이유는 구현에 의존하는 사람이 없으면 언제든지 변경할 수 있기 때문입니다. 예를 들어 백엔드 구현을 변경하여 성능을 향상시킬 수 있습니다. 구현에 의존하는 다른 모든 개발자는 중단되지만 인터페이스 사용자는 괜찮습니다. 클래스 사용자에게 영향을 미치지 않고 구현을 변경할 수있는 유연성이 있다는 것은 개인 변수를 사용하면 (보다 광범위하게 캡슐화 하면) 큰 이점이됩니다 .

또한 실제로 "신뢰 위기"가 아닙니다. 데이터를 공개하면 아무도 의존하지 않을 수 없습니다. 공개 인터페이스를 거치지 않고, 특히 마감일이 가까울 때 구현 특정 변수에 의존하는 것이 종종 편리합니다. 또한 개발자는 자신이 변경할 수있는 것에 의존한다는 것을 항상 인식하지는 않습니다.

그래서 이런 종류의 다른 질문에 대답합니다. 모든 구현 세부 사항은 비공개이어야하며 공개 부분은 클래스 사용을위한 작고 간결하고 잘 정의 된 인터페이스 여야합니다.


24
IMO는 또한 lib 작성자와 lib 소비자 간의 통신에 관한 것입니다. Public 인터페이스가 "이것을 사용"같은과 음부가 같이있는 것을 제외하고 자바에서, 당신은 "것을 사용하지 않는" 정말 그것은 개인이 그런 식으로 안전하고 명확 그래서 할 경우 사고로 사용할 수 없습니다.
chakrit

5
@chakrit 및 기타 : 개인 필드와 방법을 실제로 사용 하지 않는 사람들은 (반성을 통해) 그렇게 할 수 있습니다 . private"보안을 위해 의도 된 것이 아님"보다 적 으면 "보안"을 제공하지 않습니다. 액세스하지 않는 강력한 힌트입니다 (컴파일러를 통해 제공됨).

@delnan "우연히"라는 문구에 주목하십시오. 아마도 더 명확해야 할 것입니다.
chakrit

@ chakrit 예, 당신이 틀렸다는 것을 의미하지는 않았습니다. 나는 그 점을 홍보하고 싶었다.

1
@delnan : 개인 필드는 일부 언어에서 특정 형태의 보안을 제공합니다. 예를 들어, 액세스 수준 및 수정 자 (개인, 봉인 등)가 C #에서 보안 목적으로 사용됩니까?에 대한 Eric Lippert의 답변을 참조하십시오 . .
Brian

25

여기서 키워드는 캡슐화 입니다. OOP에서는 객체 / 클래스를 올바르게 캡슐화하기 위해 전용 변수를 사용하려고합니다.

다른 프로그래머는 당신을 사귀지 않지만 코드와 상호 작용합니다. 변수를 비공개로 만들지 않으면 전혀 해를 끼치 지 않고 자신의 코드에서 변수를 참조 할 수 있습니다. 그러나 클래스로 돌아가서 무언가를 변경해야하는 경우 더 이상 누가 어떤 변수를 사용하는지 누가 알지 알 수 없습니다. 캡슐화의 목표는 클래스의 외부 인터페이스를 명시 적으로 만들어 다른 (주로) 이러한 메서드 만 사용될 수 있음을 알 수 있도록하는 것입니다.

  1. 따라서 전용 변수는 해당 변수가 정의 클래스에만 유지되도록합니다. 변경해야 할 경우 변경 사항은 클래스 자체에 국한됩니다.

  2. C ++ 또는 Java와 같은 기존 언어에서는 일반적으로 모든 것을 비공개로 만들고 해당 게터 및 세터 만 액세스 할 수 있습니다. 실제로 많은 것을 결정할 필요가 없습니다.

  3. 때때로, f.ex. C ++ 구조체에서는 여러 가지를 함께 그룹화하는 방법으로 만 클래스가 필요합니다. 예를 들어 xy속성 만 있는 Vector 클래스를 생각해보십시오 . 이 경우 이러한 속성을 공개로 선언하여 이러한 속성에 직접 액세스 할 수 있습니다. 특히 외부의 일부 코드가 x또는에 새로운 값을 직접 작성하여 클래스의 객체를 수정하는지 신경 쓰지 않아야합니다 y.

추가 사항으로,이 문제는 다른 언어에서는 약간 다르게 간주됩니다. 예를 들어, 기능적 프로그래밍에 뿌리를 둔 언어는 데이터 불변성을 강조합니다. 즉 데이터 값을 전혀 변경할 수 없습니다. 이러한 경우 다른 프로그래머 (또는 코드)가 데이터에 대해 수행하는 작업을 신경 쓸 필요가 없습니다. 모든 데이터가 변경 불가능하기 때문에 코드에 영향을 줄 수있는 작업은 수행 할 수 없습니다.

따라서 이러한 언어에서는 균일 한 액세스 원칙을 얻습니다 . 여기서는 의도적으로 게터 및 세터와 같은 메소드를 구분하지 않지만 변수 / 함수에 직접 액세스 할 수 있습니다. 따라서 객체 지향 시나리오에서 개인 선언이 훨씬 더 널리 사용된다고 말할 수 있습니다.

또한 다른 분야를 포함하도록 지식을 넓혀 기존 개념을 완전히 새로운 방식으로 보는 방법을 보여줍니다.


1
+1 "다른 프로그래머가 당신을 사귀지 않는 동안, 그들은 당신의 코드와 상호 작용합니다." 코드를 사용하는 프로그래머는 본질적으로 악하지 않습니다. 개인 변수를 사용하면 코드를 사용하여 변수가 손상되지 않도록 할 수 있습니다. 또한 더 나은 API를 설계하고 문서화하는 데 도움이됩니다.
szalski

7

개인 변수는 나중에 객체 또는 함수의 범위를 벗어난 참조가 다른 변수에 실수로 영향을 미치지 않도록합니다. 대규모 프로그래밍 프로젝트의 경우 많은 흥미로운 문제를 피하는 데 도움이 될 수 있습니다 (일반적으로 컴파일러에서 잡히지 않음).

예를 들어, Javascript와 같은 프로토 타입 언어를 사용하면 변수가 적합 할 때 사용자가 변수를 석고로 표현할 수 있습니다.

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

해당 변수가 비공개 인 경우 외부에서 변경할 수 없습니다.

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

즉, 모든 변수가 개인용 일 필요는 없으며 개인용 변수를 과도하게 사용하면 실제로 코드가 더 번거로워 질 수 있습니다. 심각 객체에 영향을주지 않는 사소한 필드는 필요하지 않습니다 get()set()방법.

또한 개인 변수를 사용하면 많은 공용 변수의 기능에 대한 무거운 문서에 의존하지 않고도 향후 코드를 쉽게 확장 할 수 있습니다. 적은 수의 변수를 덮어 쓸 수있는 경우 실수로 기능을 중단 할 위험이 줄어 듭니다.

일반적으로 개인 변수는이를 수행 할 수 없으므로 객체 / 함수가 다른 객체 / 함수에 액세스 할 때 공용 변수를 사용해야합니다. 몇 가지에서 몇 가지 공용 변수가있을 수 있으며 올바르게 사용되는 경우 사용하는 것은 나쁘지 않습니다.


경고 3이 "uh oh!"인 이유는 분명하지 않습니다. 이 경우 아마도 프로그래머가 원했던 것일 수도 있습니다.
immibis

@immibis 아마도 아마도 대답에서 더 자세히 설명했을 것입니다. 그러나 속성에 액세스하면 구현 세부 정보를 노출 할 수 있으므로 개방형 원칙 또는 LoD와 같은 일부 OOP 원칙을 위반할 수 있습니다. '당신의 요점은 물론 그것이 정확히 무엇인지에 달려 있습니다. 대부분의 언어는 객체를 참조로 사용하며 객체 참조가 전달되고 동료 개발자가 조용히 속성을 변경하면 디버깅하기가 매우 어려울 수 있습니다. IMO 클래스 인스턴스가있는 경우 메소드로 작업하는 것이 훨씬 쉽고 확장 성이 뛰어납니다.
Jeffrey Sweeney

7

미래의 관리자와 클래스 사용자에게 이점을 인용하는 좋은 답변이 있습니다. 그러나 원래 디자인에도 이점이 있습니다. 목표는 자신이 더 쉽게 일을하게하는 시점과 클래스 사용자가 더 쉽게 일을하게되는 시점 사이에 명확한 구분 지점을 제공합니다. 공개 및 비공개 중에서 선택하면 두뇌에게 신호를 보내 하나의 모드로 전환하거나 더 나은 API로 전환합니다.

프라이버시가없는 언어가 그러한 디자인을 불가능하게 만드는 것은 아닙니다. foo.getBar()사람들 은와 같은 것을 쓰라는 프롬프트를받는 대신 게터가 쓰기가 더 쉽기 때문에 게터가 필요하지 않다고 생각하는 경향이 foo.bar있습니다 obj.container[baz].foo.bar. 더 엄격한 언어로 일한 적이없는 프로그래머는 그 문제를 보지 못할 수도 있습니다.

그렇기 때문에 프라이버시가없는 언어에서 사람들은 종종 모든 "개인"멤버에게 밑줄을 붙이는 것과 같이이를 시뮬레이션하는 이름 지정 표준을 채택합니다. 언어가 강제하지 않는 경우에도 유용한 신호입니다.


3

모든 변수는 절대적으로 공개되어야 할 필요가 없다면 개인용이어야합니다.

변수는 주로 개체의 상태를 제공하며 개인 변수는 다른 사람들이 개체의 상태를 변경하고 변경하는 것을 방지합니다.


5
주제에 대한 너무 좁은 관점. 퍼블릭 필드 액세스가 필요한 경우도 있습니다
Roland Tepp

상태를 변경할 수없는 객체 (불변 객체)를 확실히 설계 할 수 있지만 이것이 모든 클래스에 적용되는 일반적인 규칙은 아닙니다. 내 경험상, 대부분의 객체는 다른 사람들이 객체의 상태를 변경하는 것을 매우 쉽게 만듭니다.
David K

1
@DavidK bbb의 의미는 "개인 변수는 다른 사람들 이 개체의 상태를 무차별 적으로 변경하는 것을 방해 합니다." 공용 메소드는 오브젝트의 개인 상태를 변경할 수 있지만 오브젝트의 기능에 필요하고 일관된 방식으로 만 가능합니다.
맥스 나나시

@Max Nanasy : 예 . 공용 인터페이스에서 메소드 만 제공 할 때 상태가 변경되는 방식 을 제어 할 수 있습니다 . 예를 들어, 개체가 "일관성"이 되려면 충족되어야하는 구성원간에 관계가있을 수 있으며, 일관된 상태를 다른 일관된 상태로만 변경할 수 있습니다. 해당 변수가 모두 공용이면이를 시행 할 수 없습니다. 그러나 어떤 변경도 허용하지 않는 개체도있을 수 있으므로 우리가 이야기하고있는 것을 명확하게하는 것이 중요합니다.
David K

2
  • 개인 변수는 무엇을 방지하는 데 도움이됩니까?

어떤 속성과 메서드가 인터페이스이고 어떤 것이 실제로 핵심 기능인지 명확하게하는 것입니다. 퍼블릭 메소드 / 프로퍼티는 다른 코드에 관한 것으로 종종 객체를 사용하는 다른 개발자의 코드입니다. 나는 같은 프로젝트에서 100 + 이상의 팀에서 일한 적이 없지만, 내가 작성한 것을 사용하여 최대 20 명의 다른 개발자와 3-5 명의 팀을 경험 한 경험에서 다른 문제는 어리석은 것처럼 보입니다.

참고 : 저는 주로 JavaScript 개발자입니다. 나는 일반적으로 다른 개발자가 내 코드를 보는 것에 대해 걱정하지 않으며 언제든지 내 물건을 다시 정의 할 수 있다는 것을 완전히 인식하고 있습니다. 나는 그들이 무엇을하고 있는지 알기에 충분히 유능하다고 생각합니다. 그렇지 않다면 소스 컨트롤을 사용하지 않는 팀에서 일하고있을 것 같지 않습니다.

  • 특정 속성 집합이 개인용인지 아닌지를 어떻게 결정합니까? 기본적으로 모든 필드가 비공개이어야한다면 왜 클래스에 공개 데이터 멤버가 있습니까?

나는 당신이 실제로 어떤 종류의 검증이나 설정 될 다른 특별한 처리를 수행하지 않을 때 사유지에 게터와 세터를 두는 것이 바보라고 생각했습니다. 나는 항상 그것이 항상 필요하다고 생각하지는 않지만, 대규모, 높은 복잡성을 처리 할 때 가장 중요한 것은 일관된 방식으로 동작하는 객체에 의존하는 다른 많은 개발자가 일을하는 것이 유용 할 수 있습니다 일관되고 균일 한 방법. 사람들이 볼 때 방법은 전화 getThatsetThat, 그들은 의도가 무엇인지 정확히 알고 있으며, tomahtos보다는 항상 토마토를 얻을 것이라는 기대로 당신과 상호 작용하기 위해 물건을 쓸 수 있습니다. 그렇지 않은 경우 객체가 원하지 않는 것을 제공한다는 것을 알고 있으므로 다른 객체가 해당 데이터로 수행하지 않아야 할 데이터를 허용합니다. 필요에 따라 제어 할 수 있습니다.

또 다른 큰 장점은 다양한 종류의 상태 컨텍스트에 따라 객체가 게터 또는 세터와 다르게 값을 전달하거나 해석하는 것이 더 쉽다는 것입니다. 그들은 메소드를 사용하여 물건에 액세스하기 때문에 나중에 의존하는 다른 코드를 손상시키지 않고 객체의 작동 방식을 훨씬 쉽게 변경할 수 있습니다. 중요한 원칙은 객체 만 실제로 담당 한 데이터를 변경한다는 것입니다. 이것은 코드를 느슨하게 결합하는 데 특히 중요하며 이식성과 수정의 용이성 측면에서 큰 승리입니다.

  • 어떤 상황에서 변수를 공개해야합니까?

일급 함수 (함수를 인수로 전달할 수 있음)를 사용하면 소규모 프로젝트에서 그렇게 할 필요가없는 것 이외의 많은 큰 이유를 생각할 수 없습니다. 그것없이, 나는 당신이 다른 데이터에 의해 엄청나게 정기적으로 처리되는 멤버를 가질 수 있다고 생각합니다. 그 자체로 왜 객체가 그 데이터를 담당했는지 궁금해 할 것입니다. 일반적으로 말하자면 공개 데이터 속성을 결정하기 전에 결함에 대해 아키텍처를 다시 검사하는 경향이 있습니다. IMO, 일반적으로 나쁜 생각을하는 것을 허용하는 언어에는 아무런 문제가 없습니다. 일부 언어는 동의하지 않습니다.


IMHO, 공개 변수를 공개 하는 것이 유일한 목적인 공개 클래스를 갖는 데는 아무런 문제가 없습니다 . 실제로, JVM은 그 목적을 위해 내장 클래스의 번호를 가지고 : int[], double[], Object[], 등 하나는해야하지만, 하나는 이러한 클래스의 인스턴스를 노출하는 방법에 대한 매우주의해야합니다. 의 위치에 어떤 영향 을 미칠지 확실하지 않기 때문에 void CopyLocationTo(Point p);[ Point호출자로부터의 수락 ] 의 의미 는보다 명확 합니다. Point location()Point pt = foo.location(); pt.x ++;foo
supercat

2

SO에 대한 관련 질문이 게시물을 참조하십시오 .

단점은 변수 범위를 통해 코드 소비자에게 엉망이되거나해서는 안되는 것을 보여줄 수 있다는 것입니다. 전용 변수는 전체 객체가 일관된 상태를 유지하도록 속성 설정 기 또는 처리 방법을 사용하여 "검토 된"데이터를 보유 할 수 있습니다. 전용 변수의 값을 직접 변경하면 객체가 일치하지 않을 수 있습니다. 그것을 비공개로 만들면 누군가가 열심히 일하고 변경하기 위해 실제로 높은 런타임 권한을 가져야합니다.

따라서 적절한 구성원 범위 지정은 자체 문서화 코드의 핵심입니다.


2

실제 예를 사용하여 다른 관점에서 캡슐화의 가치에 대해 이야기하겠습니다. 꽤 오래 전에 (80 년대 초), Daggorath의 Dungeons라는 Radio Shack Color Computer 용 게임이 개발되었습니다. 몇 년 전, Richard Hunerlach는이를 종이 어셈블러 목록에서 C / C ++ ( http://mspencer.net/daggorath/dodpcp.html )로 포팅했습니다 . 얼마 후, 나는 코드를 얻었고 더 나은 캡슐화를 제공하기 위해 코드를 리팩터링하기 시작했습니다 ( http://dbp-consulting.com/stuff/ ).

이 코드는 이미 일정, 비디오, 사용자 입력, 던전 생성, 괴물 등을 처리하기 위해 다른 객체로 고려되었지만 어셈블러에서 이식되었다는 것을 분명히 알 수 있습니다. 가장 큰 임무는 캡슐화를 늘리는 것이 었습니다. 즉, 코드의 다른 부분을 가져와 서로의 사업에서 코를 빼내는 것을 의미합니다. 예를 들어, 비디오 변수를 직접 변경하여 영향을 줄 수있는 곳이 많이있었습니다. 일부는 오류 검사로 수행했지만 일부는 그 변경의 의미에 대해 미묘하게 다른 아이디어를 가지고있었습니다. 코드가 많이 중복되었습니다. 대신 비디오 섹션에는 원하는 작업을 수행 할 수있는 인터페이스가 필요했으며이를 수행하는 코드는 모두 한곳, 하나의 아이디어, 한곳에서 디버깅 할 수 있습니다. 그런 종류의 일이 만연했습니다.

코드가 깨지기 시작하면서 진단조차되지 않은 버그는 사라졌습니다. 코드의 품질이 향상되었습니다. 각 작업은 코드에서 한 곳의 책임이되었으며 제대로 할 수있는 곳은 한 곳뿐이었습니다. (나는 여전히 코드를 다시 통과 할 때마다 더 많은 것을 찾습니다.)

코드에서 볼 수있는 모든 것은 인터페이스입니다. 당신이 그것을 의미하는지 아닌지. 가시성을 최대한 제한하면 나중에 잘못된 위치에 코드를 배치하려는 유혹을받지 않을 것입니다. 코드의 어떤 부분이 어떤 데이터를 담당하는지 분명하게합니다. 더 좋고 깨끗하고 단순하며 우아한 디자인을 만듭니다.

객체가 자신의 데이터를 담당하고 발생해야하는 다른 모든 사람에게 인터페이스를 제공하면 코드가 훨씬 간단 해집니다. 그냥 빠진다. 하나의 일만하는 작은 간단한 루틴이 있습니다. 덜 복잡한 == 적은 버그.


"lib 사용자의 자유"와 "우리에게 적은 문제"사이의 어려운 균형. 캡슐화가 내 코딩에서 버그를 방지한다는 점에서 더 낫다는 것을 믿기 시작했으며 최종 사용자도 버그를 방지하는 데 도움이됩니다. 그러나 자유의 결여로 인해 대안을 찾아야 할 수도 있습니다. 아직 사용되지 않았지만 공개 방법을 통해 예상되는 기능을 통해 균형을 잡는 데 도움이 될 수 있지만 더 많은 시간이 소요될 수 있습니다.
물병 자리 힘

리팩토링 된 버전이 github에없는 것이 너무 나쁩니다.
jmoreno

2

그것은 신뢰에 대한 두려움이나 공격에 대한 두려움과는 관련이 없으며, 캡슐화에 관한 것입니다. 강의 사용자에 대한 불필요한 정보를 강요하지 않습니다.

개인 상수를 고려하십시오-비밀 값을 포함해서는 안되며 (다른 곳에 저장해야 함) 변경 할 수 없으며 클래스에 전달 할 필요가 없습니다 (그렇지 않으면 공개해야 함). 그것들에 대한 유일한 사용은 OTHER 클래스의 상수입니다. 그러나 그렇게하면, 그 수업은 이제 수업과 관련이없는 일을하기 위해 수업에 의존합니다. 상수를 변경하면 다른 클래스가 중단 될 수 있습니다. 그것은 양쪽면에서 나쁘다. 당신은 학급의 작가로서 가능한 한 많은 것을 자유롭게 바꾸고 싶어하고 통제 할 수없는 것들에 대해 걱정하고 싶지 않다. 클래스의 소비자는 클래스 변경 및 코드 중단에 대한 걱정없이 클래스의 노출 된 세부 사항에 의존 할 수 있기를 원합니다.

수업의 소비자는 수업과 상호 작용하는 데 필요한 모든 것을 알고 싶어하며 수업 방식에 영향을주지 않는 수업에 대해서는 아무 것도 알고 싶지 않습니다. 반사와 함께 언어를 사용했다면, 얼마나 자주 어떤 클래스가 무언가를 수행하는지 또는 예외를 던지는 곳을 배우지 않고 개인 필드와 메소드의 이름을 배우는 데 얼마나 자주 사용 했습니까? 나는 결코 내기를하지 않습니다. 그 지식에는 쓸모가 없기 때문입니다.


1

OOP 개념에는 상속 기능이 있습니다 (자바 또는 C ++). 따라서 상속을 받으면 (상속 된 클래스의 변수에 액세스한다는 의미) 해당 변수에 영향을 줄 가능성이 있습니다. 따라서 변수를 변경할 수 있는지 여부를 결정해야합니다.

이러한 목적으로 만 OOP에서 액세스 수정자를 사용하고 있습니다. 수정 자 중 하나는 개인용이므로 해당 클래스에서만 액세스 할 수 있습니다. 다른 클래스는 해당 변수에 영향을 줄 수 없습니다.

아시다시피 protected는 상속 할 클래스가 액세스 할 수 있음을 의미합니다.

OOP에 수정 자 개념이있는 이유는 이러한 이유 때문입니다 (모든 클래스가 OOP 개념을 사용하여 다른 클래스 변수에 액세스 할 수 있음). 수정 자 개념이 없으면 클래스를 상속하거나 다른 OOP 개념을 사용하는 것이 어려웠을 것입니다.


1

다른 사람들이 말했듯이 개인 변수는 객체가 일관성이없는 상태로 이어지는 미스 사용을 피하고 버그와 예기치 않은 예외를 추적하기가 어렵습니다.

그러나 다른 한편으로는 대부분 다른 사람들이 무시한 것은 보호 된 분야에 관한 것입니다.

확장 된 하위 클래스는 보호 된 필드에 대한 전체 액세스 권한을 가지므로 해당 필드가 공용 인 것처럼 개체를 취약하게 만들 수 있지만 해당 취약성은 해당 클래스를 더 많이 노출하지 않는 한 자체 확장 클래스로 제한됩니다.

따라서 공개 필드는 좋은 것으로 간주하기가 어렵고 현재까지 사용하는 유일한 이유는 구성 매개 변수로 사용되는 클래스에 대한 것입니다 (필드가 많고 논리가없는 매우 간단한 클래스이므로 클래스는 매개 변수로만 전달됩니다) 일부 방법).

그러나 개인 필드는 다른 사용자에 대한 코드의 유연성을 낮 춥니 다.

유연성 대 문제, 장단점 :

보호 필드가있는 바닐라 클래스에서 코드로 인스턴스화 된 객체는 안전하며 전적으로 귀하의 책임입니다.

반면, 코드 사용자가 인스턴스화 한 보호 필드로 클래스를 확장하는 객체는 사용자의 책임이 아니라 책임입니다.

따라서 잘 문서화되지 않은 보호 필드 / 방법 또는 사용자가 이러한 필드와 방법을 어떻게 사용해야하는지 실제로 이해하지 못하는 경우 자신과 사용자에게 불필요한 문제를 일으킬 가능성이 높습니다.

다른 한편으로, 대부분의 물건을 사적인 것으로 만들면 사용자의 유연성이 떨어지고, 일을 처리하기 위해 포크를 만들고 유지하기를 원하지 않을 수 있기 때문에 유지 관리되는 대안을 찾지 않아도 될 수도 있습니다.

따라서 개인, 보호 및 공공의 균형이 정말 중요합니다.

이제 개인과 보호를 결정하는 것이 진짜 문제입니다.

언제 보호를 사용해야합니까?

필드가 매우 유연하다는 것을 이해할 때마다 보호 된 것으로 코딩해야합니다. 그 유연성은 null이되는 것 (null이 항상 확인되고 예외를 발생시키지 않는 유효한 상태로 인식되는 것)에서 클래스 ex에 의해 사용되기 전에 제약 조건을 갖는 것까지입니다. > = 0, <100 등이며 초과 / 미달 유량 값에 대해 자동으로 고정되어 최대 경고 메시지를 표시합니다.

따라서 보호 된 필드의 경우 getter를 만들고 필드 변수를 직접 사용하는 대신 게터를 사용할 수 있지만 다른 사용자는 특정 코드에 대한 유연성을 원할 경우 사용하지 않을 수 있습니다. : 확장 클래스에서 음수 값을 올바르게 사용하려는 경우.


-1

imo @tdammers는 옳지 않으며 실제로 오도합니다.

구현 세부 사항을 숨기는 개인 변수가 있습니다. 수업에서 점수를 저장 A하기 array위해를 사용하고있을 수 있습니다 . 내일은 tree또는 priority queue대신 에 사용할 수 있습니다 . 수업에 필요한 모든 사용자는 점수와 이름을 입력 addScore()하는 방법과 누가 상위 10 명인지 알아내는 방법 getTop(n)입니다.

기본 데이터 구조에 액세스 할 필요가 없습니다. 좋아? 글쎄, 몇 가지주의 사항이 있습니다.

어쨌든 많은 상태를 저장해서는 안되며, 대부분은 필요하지 않습니다. 저장 상태는 특정 클래스로 "분리 된"경우에도 코드를 복잡하게 만듭니다. 다른 객체가 해당 클래스의 메소드를 호출했기 때문에 개인 변수가 변경되었을 수 있습니다. 여전히 언제 어디서 그 메소드가 호출되었고 그 공개 메소드가 이론적으로 어디서나 호출 될 수 있는지 알아 내야합니다.

가장 좋은 방법은 프로그램에 포함 된 상태의 양을 제한하고 가능한 경우 순수한 기능을 사용하는 것입니다.


-1
  • 변수에 액세스한다는 것은 프로그램이 실행될 때 값에 액세스하는 것을 의미하며, 변수를 private로 설정 하면 코드가 실행될 때 값을 보호 합니다.
  • 소위 "데이터 숨기기"의 요점은 클래스를 사용하는 다른 클래스에서 내부 데이터를 숨기는 것입니다. 이러한 다른 클래스는 변수 값을 직접 변경하지 않고 클래스에서 메서드를 호출하여 동작에 액세스해야합니다.
  • 변수를 개인용 데이터 멤버로 만들면 값이 수정되거나 변경되지 않도록보다 쉽게 ​​확인할 수 있습니다. 반면에 변수가 공용 인 경우 다른 클래스가 값을 수정하거나 변경하여 코드의 다른 부분이 충돌 할 수 있습니다.

1
포인트를 만든 전에 17 답 설명을 통해이 상당한 아무것도 제공하지 않는 것
모기

-4

먼저 객체 지향 프로그래밍의 개념을 이해해야합니다. 추상화, 캡슐화 등이 있습니다.

추상화-구현의 세부 사항을 알 필요없이 논리에 대한 아이디어를 얻습니다.

캡슐화-개체의 밑줄 구현을 볼 수 없습니다. 객체의 공용 인터페이스 만 볼 수 있습니다.

이제 C #, Java, C ++와 같은 객체 지향 프로그램 중 하나를 사용하여 특정 구현에서 이러한 개념을 구현할 수 있습니다.

private-외부 세계에서 숨겨져 야하는 구현입니다. 변경할 수 있도록 수업의 사용자는 영향을받지 않습니다.

public-객체를 사용할 수있는 인터페이스입니다.


1
protected-서브 클래스 (확장자) (java)에 의해 직접 액세스 가능
물병 자리 힘
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.