development

비공개 대 보호됨-가시성 실용성 문제

big-blog 2020. 6. 27. 10:11
반응형

비공개 대 보호됨-가시성 실용성 문제


나는 찾고 있었고 이론적 인 차이점을 알고 있습니다.

  • public- 모든 클래스 / 함수가 메소드 / 프로퍼티에 액세스 할 수 있습니다.
  • protected- 이 클래스와 하위 클래스 만 메소드 / 속성에 액세스 할 수 있습니다.
  • 개인 - 만이 클래스는 메소드 / 속성에 액세스 할 수 있습니다. 심지어 상속되지도 않습니다.

그게 다 괜찮습니다. 문제는 그들 사이 실제 차이점은 무엇입니까? 언제 사용 private하고 언제 사용 protected하시겠습니까? 이 표준에 대한 표준 또는 허용 가능한 모범 사례가 있습니까?

지금까지 상속과 다형성의 개념을 유지하기 public위해 외부에서 액세스 해야하는 모든 것 (생성자 및 메인 클래스 기능과 같은)과 protected내부 메서드 (논리, ​​도우미 메서드 등)에 사용합니다. 내가 올바른 길을 가고 있습니까?

(이 질문은 저를위한 것이지만이 질문과 같은 질문을 보지 않았으므로 나중에 참조 할 수 있습니다).


아니요, 당신은 올바른 길을 가고 있지 않습니다. 경험상 가장 좋은 방법은 모든 것을 가능한 한 비밀로 만드는 것입니다. 이를 통해 클래스를보다 캡슐화 할 수 있으며 클래스를 사용하는 코드에 영향을주지 않고 클래스 내부를 변경할 수 있습니다.

클래스를 상속 가능하도록 디자인하는 경우 서브 클래스에서 재정의하고 액세스 할 수있는 항목을 신중하게 선택하고 보호되도록합니다 (그리고 액세스 가능하지만 재정의 할 수 없도록하려면 Java에 대해 이야기하십시오). 그러나 클래스의 서브 클래스를 갖도록 허용하고 보호 된 필드 또는 메소드가있는 경우이 필드 또는 메소드는 클래스의 공용 API의 일부이므로 서브 클래스를 중단하지 않고 나중에 변경할 수 없습니다.

상속되지 않는 클래스는 최종적으로 작성해야합니다 (Java). 단위 테스트를 위해 일부 액세스 규칙 (비공개, 최종, 비 최종)을 완화 할 수 있지만 문서화 한 다음 방법이 보호 되어도 재정의되지 않아야한다는 점을 분명히해야합니다.


여기서는 주로 메소드 액세스에 대해 이야기하고 있고 클래스 멤버 액세스가 아닌 최종 클래스로 표시되는 방법을 설명 합니다.

오래된 지혜

"좋은 이유가없는 한 비공개로 표시하십시오."

오픈 소스가 개발자 라이브러리 공간과 VCS / 종속성 관리 시스템을 지배하기 전까지는 며칠 만에 이해가되었습니다. Github, Maven 등 덕분에 하이퍼 콜라보레이션이되었습니다. 그 당시에는 라이브러리를 활용할 수있는 방법을 제한하여 돈을 벌었습니다. 나는 아마도이 "모범 사례"를 엄격히 고수하면서 경력의 첫 8 ~ 9 년을 보냈다.

오늘 나는 그것이 나쁜 조언이라고 믿습니다. 때로는 메소드를 private 또는 class final로 표시하는 데 합리적인 주장이 있지만, 매우 드물고 심지어 개선되지 않을 수도 있습니다.

넌 해본 적 있니:

  • 상속과 몇 줄의 코드로 해결할 수있는 버그가있는 라이브러리 등으로 실망하거나 놀랐거나 상처를 받았지만 비공개 / 최종 방법과 클래스로 인해 절대로 올 수없는 공식 패치를 기다려야합니까? 나는 가지고있다.
  • 저자가 상상 한 것과 약간 다른 유스 케이스에 라이브러리를 사용하고 싶었지만 개인 / 최종 방법 및 클래스로 인해 라이브러리를 사용할 수 없었습니까? 나는 가지고있다.
  • 확장성에 지나치게 허용되는 라이브러리 등으로 인해 실망하거나 놀랐거나 다쳤습니까? 나는하지 않았다.

다음은 기본적으로 비공개 메소드 표시에 대해 들어 본 3 가지 합리화입니다.

합리화 # 1 : 안전하지 않으며 특정 방법을 재정의 할 이유가 없습니다.

필자가 작성한 특정 방법을 재정의해야하는지 여부에 대해 내가 틀린 횟수를 셀 수 없습니다. 몇 가지 인기있는 오픈 소스 라이브러리에서 작업 한 후, 사물을 표시하는 실제 비용을 어려운 방법으로 배웠습니다. 예상치 못한 문제 나 사용 사례에 대한 실질적인 해결책을 종종 제거합니다. 반대로, 저는 16 년 이상 전문 개발에 API 안전과 관련된 이유로 개인이 아닌 보호 된 방법을 표시하는 것을 후회 적이 없습니다 . 개발자가 클래스를 확장하고 메서드를 재정의하기로 선택하면 의식적으로 "내가하는 일을 알고 있습니다"라고 말합니다. 생산성을 위해 충분해야합니다. 기간. 위험한 경우, 클래스 / 메소드 Javadocs에서주의하십시오. 맹목적으로 문을 닫지 마십시오.

기본적으로 보호되는 표시 방법은 현대 SW 개발의 주요 문제 중 하나 인 상상력 상실의 완화입니다.

합리화 # 2 : 공용 API / Javadoc을 깨끗하게 유지

이것은 더 합리적이며 대상 고객에 따라 올바른 일이 될 수도 있지만 API를 "깨끗하게"유지하는 비용이 실제로 무엇인지 고려할 가치가 있습니다. 위에서 언급 한 이유로, 경우에 따라 기본적으로 보호되는 항목을 표시하는 것이 더 합리적입니다.

합리화 # 3 : 내 소프트웨어는 상용이므로 사용을 제한해야합니다.

이것은 합리적이지만 소비자는 매번 품질에 차이가 없다고 가정 할 때 덜 제한적인 경쟁 업체와 함께 갈 것입니다.

절대 말하지 마

나는 결코 메소드를 개인용으로 표시하지 않는다고 말하지 않는다. 더 나은 경험 법칙은 "좋은 이유가 없다면 방법을 보호하는 것"입니다.

이 조언은 모듈로 나뉘어 진 라이브러리 또는 대규모 프로젝트에서 작업하는 사람들에게 가장 적합합니다. 더 작거나 더 많은 모 놀리 식 프로젝트의 경우 어쨌든 모든 코드를 제어하기 때문에 그다지 중요하지 않으며 필요할 때 / 필요할 때 코드의 액세스 수준을 쉽게 변경할 수 있습니다. 그럼에도 불구하고, 나는 여전히 똑같은 조언을 줄 것입니다 :-)


개인 필드 학대 중지!

여기의 의견은 개인 필드 사용에 대해 압도적으로지지적인 것으로 보입니다. 글쎄, 다른 말이 있습니다.

사적인 분야는 원칙적으로 좋은가? 예. 그러나 황금률 이라는 말 은 확실 하지 않을 때 모든 것을 비공개로 만드는 것입니다 . 문제가 발생할 때까지 문제가 표시되지 않습니다. 내 의견으로 는 확실하지 않은 경우 필드를 보호 된 것으로 표시해야 합니다.

클래스를 확장하려는 두 가지 경우가 있습니다.

  • 기본 클래스에 추가 기능을 추가하려고합니다
  • 현재 패키지 외부에있는 기존 클래스를 수정하려고합니다 (일부 라이브러리에서)

첫 번째 경우 개인 필드에는 아무런 문제가 없습니다. 사람들이 개인 필드를 남용한다는 사실은 똥을 수정할 수 없다는 것을 알게되면 너무 실망 스럽습니다.

자동차를 모델링하는 간단한 라이브러리를 고려하십시오.

class Car {
    private screw;
    public assembleCar() {
       screw.install();
    };
    private putScrewsTogether() {
       ...
    };
}

The library author thought: there's no reason the users of my library need to access the implementation detail of assembleCar() right? Let's mark screw as private.

Well, the author is wrong. If you want to modify only the assembleCar() method without copying the whole class into your package, you're out of luck. You have to rewrite your own screw field. Let's say this car uses a dozen of screws, and each of them involves some untrivial initialization code in different private methods, and these screws are all marked private. At this point, it starts to suck.

Yes, you can argue with me that well the library author could have written better code so there's nothing wrong with private fields. I'm not arguing that private field is a problem with OOP. It is a problem when people are using them.

The moral of the story is, if you're writing a library, you never know if your users want to access a particular field. If you're unsure, mark it protected so everyone would be happier later. At least don't abuse private field.

I very much support Nick's answer.


I read an article a while ago that talked about locking down every class as much as possible. Make everything final and private unless you have an immediate need to expose some data or functionality to the outside world. It's always easy to expand the scope to be more permissible later on, but not the other way around. First consider making as many things as possible final which will make choosing between private and protected much easier.

  1. Make all classes final unless you need to subclass them right away.
  2. Make all methods final unless you need to subclass and override them right away.
  3. Make all method parameters final unless you need to change them within the body of the method, which is kinda awkward most of the times anyways.

Now if you're left with a final class, then make everything private unless something is absolutely needed by the world - make that public.

If you're left with a class that does have subclass(es), then carefully examine every property and method. First consider if you even want to expose that property/method to subclasses. If you do, then consider whether a subclass can wreak havoc on your object if it messed up the property value or method implementation in the process of overriding. If it's possible, and you want to protect your class' property/method even from subclasses (sounds ironic, I know), then make it private. Otherwise make it protected.

Disclaimer: I don't program much in Java :)


When would you use private and when would you use protected?

Private Inheritance can be thought of Implemented in terms of relationship rather than a IS-A relationship. Simply put, the external interface of the inheriting class has no (visible) relationship to the inherited class, It uses the private inheritance only to implement a similar functionality which the Base class provides.

Unlike, Private Inheritance, Protected inheritance is a restricted form of Inheritance,wherein the deriving class IS-A kind of the Base class and it wants to restrict the access of the derived members only to the derived class.


Well it is all about encapsulation if the paybill classes handles billing of payment then in product class why would it needs the whole process of billing process i.e payment method how to pay where to pay .. so only letting what are used for other classes and objects nothing more than that public for those where other classes would use too, protected for those limit only for extending classes. As you are madara uchiha the private is like "limboo" you can see it (you class only single class).

참고URL : https://stackoverflow.com/questions/8353272/private-vs-protected-visibility-good-practice-concern

반응형