문제

나는 사용하지 않는 상속하지만,경우에는 사용하지 않을 보호 특성 때문에 나는 그것을 나누기의 캡슐화된 클래스입니다.

당신이 사용하여 보호되는가?당신은 무엇을 사용하는가?

도움이 되었습니까?

해결책

인터뷰 에 의해 디자인 빌 Venners,여호수아는 블로흐의 작성자 효과적인 자바 말합니다:

신뢰 서브 클래스

빌 Venners: 해야 하 신뢰보다는 더 친밀하게 서브 클래스 non-서브 클래스는?예를 들어,내가 할인 그것은 쉽게 위해 서브 클래스 구현하는 나에게 휴식보다 나 것이 아닌 클래스?에 특히,에 대해 어떻게 느끼 보호된 데이터는?

조 블: 뭔가를 쓰는 것은 모두고 강력한 subclassable 에 대한 악의적인은 서브 클래스 실제로 꽤 힘든 것은, 가정을 제공 서브 클래스에 액세스 내부 데이터 구조입니다.는 경우 서브 클래스에 액세스할 수 없 는 아무것도 일반 사용자 지 않는,다음에 대한 어렵게 서브 클래스는 손상을 수행하.그러나지 않는 한 당신 모든 방법을 결승전 서브 클래스는 여전히 휴식 계약하여 잘못된 것에 응답하는 방법 호출을 기반으로 합니다.는 정확하게는 이유 보안 중요한 클래스를 다음과 같 문자열 최종 있습니다.그렇지 않으면 누군가 하위 클래스를 작성는 문자열 나타나 변경하는 것 충분한 휴식하 보안입니다.그래서 당신 신뢰해야 합니다 당신의 하위 클래스.는 경우 는 그들을 신뢰하지 않는,당신은 허용할 수 없 그들기 때문에 하위 클래스로 그렇게 쉽게 인 등을 위반하는 그것의 계약입니다.

멀리로 보호되는 데이터에서는 일반적으로, 그것은 필요악이다.야 최소로 유지된다.대부분의 데이터 보호 와 보호 방법 금액 투입하여 구현 세부 사항입니다.보호된 필드 구현 정보는 당신이 기 보기 서브 클래스.도 보호된 방법입니다 조각의 내부 구조는 당신 시 서브 클래스.

이 표시는 그것은 종종할 수 있도록 하는 데 필요한 서브 클래스를 자신의 일을,또는 마 그것을 효율적으로 합니다.하지만 일단 당신 그것은,당신은 당해드리기 위해 노력하고 있습니다.그것은 지금 무언가가는 당신은 허용되지 을 변경하는 경우에도,당신이 나중에 찾아보 효율적인 구현에는 없 더 이상의 사용을 포함 특정 분야 또는 방법입니다.

그래서 다른 모든 것들이 동일하다면,당신 없이 사용할 수 있을 보호원 다.그러나 그는 말했다,당신은 너무 다음 몇 가지의 클래스를 사용할 수 없는 경우가 있습니다 로 슈퍼스 클래스,또는 적어도 하지 효율적인 수퍼 클래스입니다.자주 당신 알아 사후에 이를 공지합니다.나의 철학 는 몇 가지 보호 구성원으로 가능한 경우 먼저 작성 클래스입니다.다음을 시도하는 클래스.당신 는 것을 찾을 수 있습니다없이 특정 보호된 방법에서,모든 서브 클래스이 해야 할 나쁜 것입니다.

예를 들어,당신 AbstractList, 을 찾을 수 있는 거기에 보호된 방법을 삭제할 의 범위 목록이 한 번에 (removeRange).그 이유는 무엇입에 있는가?기 때문에 정상적인 관용구 제거 범위에 따라 공개 API,가 전화 subList 을 얻는 하위List, 다음 clear 그 서브List.지 않고 이 특정한 보호 방법,그러나,만 일 clear 이 할 수 있는 반복적으로 제거 개별적인 요소입니다.

그것에 대해 생각합니다.배열이 있는 경우 표현,그것은 무엇을 할 것인가?그 를 반복적으로 축소 배열 을 하기 위해 N 작동 N 다.그래서 그것은 것입니다 을 이차 양의 작업 신의 선형 양의 작업 그것이 해야 합니다.제공하여 이 보호된 방법을 우리는 어떠한 허용 구현할 수 있는 효율적으로 삭제하려면 전체 범위니다.고 모든 합리적인 List 구현 삭제할 수 있습 범위를 더 효율적으로 니다.

우리는 것이 보호 방법은 무언가를 당신 방법보다 더 똑똑하다는 것을 알게 up 다.기본적으로 구현 것입니다.그런 다음,우리가 시작해 서브 클래스 그것은,우리는 깨달 범위를 삭제하였 차입니다.우리가 감당할 수 없는,그래서 나에 넣어 보호되는 방법입니다.나는 생각한 는 최고의 접근 방식 보호된 방법입니다.에 넣어로 가능한 다음,더 추가로 필요합니다.보호된 방법을 나타내 약속을 디자인할 수 있는 변경하고 싶습니다.항상 추가할 수 있습니다 보호 방법,그러나 당신이 걸릴 수 없습니다 습니다.

빌 Venners: 과 데이터를 보호?

조 블: 같은 일이지만,더 많은.보호된 데이터가 더 위험의 측면에서 엉망으로 데이터 invariants.만약 당신이 누군가에게 다른 일부에 대한 액세스 내부의 데이터 그들은 자유로운 통치합니다.

짧은 버전을 사용:그것은 나누기 캡슐에 넣기만 필요한 악어야 하는 최소한으로 유지됩니다.

다른 팁

C#:

내가 사용하는 보호를 위한 추상적인 또는 가상의 방법이 내가 원하는 기업을 재정의합니다.나도는 방법을 보호하는 경우 그 소집할 수 있는 기본 클래스,그러나 나는 그것을 원하지 않는 외부에서 호출되는 클래스 계층 구조입니다.

필요할 수 있는 정적(또는'글로벌')특성 당신은 당신의 서브 클래스나 클래스에서는 동일한 패키지(만약 그것에 대해 자바)에 있습니다.

그 static final 특성을 나타내는 어떤 종류의'상수 값이'거 getter 함수,그래서 protected static final 특성 의미가 있습에서는 케이스.

스코트 마이어스는 말 용 보호 속에서 효과적인 C++(3rd ed.):

항목 22:선 데이터 구성원 개인이다.

그 이유는 동일한 당신을 제공:그것은 나누기 제품.결과는 그렇지 않으면 현지 문화를 소개하는 이미지를 업로드하는 클래스의 수 따라 형식과 결과에서 변경 다른 많은 장소입니다.

없습니다 좋은 이유를 보호한 특성이 있습니다.기본 클래스 할 수 있어야합에 따라 달라집 상태를 의미하는 액세스 제한을 통해 데이터 접근 방법이 있습니다.을 제공하지 못할 사람이 귀하의 개인 데이터에 액세스 할 수도이다.

protected 키워드는 개념에 오류가 언어와 디자인 아,그리고 여러 현대적인 언어와 같은 Nim 및 실론(참조하십시오 http://ceylon-lang.org/documentation/faq/language-design/#no_protected_modifier),하게 디자인 보다는 오히려 그냥 복사하는 일반적인 실수를 하지 않은 이러한 키워드를 사용합니다.

그것은 보호되지 않는 멤버 나누기 캡슐에 넣기,그것은 노출원에 노출되지 않아야하는 것을 나누기 캡슐에 넣기...그것이 문제가되지 않는지 여부를 보호하거나 공개한다.의 문제 protected 는 wrongheaded 와 오해의 소지가...선언원 protected (보 private)을 보호하지 않을,그것이 반대로 정확하게 public 는 않습니다.보호된 구성원에 액세스 할 수있는 것 외의 클래스,을 세계에 노출되고 그래서 그 의미가 유지되어야 영원히,다만의 경우와 같이 public.전체적인 아이디어의"보호"는 말도...캡슐에 넣기는지 보안,그리고 그냥 키워드 진행되면 혼란이다.에 도움을 줄 수 있습니다 작은 피함으로써 모든 사용 protected 에서 자신의 클래스--무언가가는 내부의 부분을 구현하지 않는 부분의 클래스의 의미,그리고 나중에 변경될 수 있습,그리고 그것은 개인이나 내부의 패키지,모듈,어셈블리,등등.는 경우는 변경할 수 없는 부분의 클래스는 의미,그리고 그것은 공개,그리고 당신은 없을 것을 귀찮게 사용자의 사람이 볼 수있는 유용한 회원에서 그러나 그것을 사용할 수 없지 않는 한 그들이 만드는 자신의 인스턴스에서 얻을 수있는 그것에 의해 서브 클래스.

나는 사용하지 않는 특성을 보호 Java 기 때문에 그들만 패키지 보호된다.하지만에서는 C++,난 그들을 사용하는 추상 클래스에서 허용,상속받은 클래스를 상속적으로 적용됩니다.

일반적으로,아무도 당신이 정말로 사용하고 싶지 않은 보호되는 데이터는 회원입니다.이것은 이중 사실이 당신의 쓰는 API 입니다.면 누군가에서 상속되는 클래스할 수 있는지 정말로 정비하지 않게 휴식에서 그들을 이상하고 때로는 야생의 방법입니다.

나는 생각해 보호되는 특성은 나쁜 생각이 아니다.내가 사용하는 CheckStyle 을 적용하는 규칙으로 내 자바 개발 팀이 있습니다.

나는 최근에 프로젝트에 근무했다"보호"회원은 아주 좋은 생각입니다.클래스며,해당은 같은 것이었다:

[+] Base
 |
 +--[+] BaseMap
 |   |
 |   +--[+] Map
 |   |
 |   +--[+] HashMap
 |
 +--[+] // something else ?

기본 구현 std::list 그러나 다른 아무것도 있습니다.에 직접 액세스 목록을 금지된 사용자에게,그러나 기본 클래스가 완료되지 않았,그것은 어쨌든 의존에서 파생된 클래스를 구현하는 간접을하시기 바랍니다.

간접에서 올 수 있었는 적어도 두 개의 맛:std::도 stdext::해시 맵.두 맵을 동일한 방식으로 동작하지만 사실은 해시 맵 필요한 키를 해쉬(에 VC2003,castable 을 size_t).

그래서 베이스맵을 구현 TMap 으로 템플릿화하는 형식이었지도 같은 컨테이너입니다.

지도 HashMap 두 개의 파생된 클래스의 베이스맵을 전문으로 하나 베이스맵에서는 std::지도,그리고 다른 stdext::해시 맵.

그래서:

  • 료되지 않았으로 사용할 수 있러(공용 접근!) 만 제공되는 일반적인 기능과 코드

  • 베이스맵 필요한 쉽게 읽기/쓰기 std::list

  • 지도 HashMap 필요한 쉽게 읽기/쓰기 권한을 TMap 에서 정의 베이스맵.

한 유일한 솔루션을 사용하여 보호에 대한 std::list 및 TMap 구성원 변수입니다.방법이 없었다 나는 그를"개인 때문에"내가 어쨌든 모든 노출시키거나 거의 모든 기능을 통해 읽기/쓰기 접근이 어쨌든.

끝에서,내 생각하는 경우 en 까지 나누어의 클래스로,여러 개체,각각 유도 추가하는 데 필요한 기능의 어머니 클래스고,가장 파생되는 클래스를 정말 사용 가능한 다음,보호되는 방법입니다.사실은 보호"회원"이었고,그래서 거의 불가능하고,도움을 주었다.

하지만 그렇지 않으면 보호되는 피해야 한다 가능한 한 많은(즉:사용은 기본적으로 개인,공공해야 하는 경우에 노출방법).

나는 그들을 사용합니다.에서 짧은,그것의 좋은 방법이하려는 경우,어떤 특성을 공유합니다.여 작성할 수 있습니다 set/get 기능들을 위해,그러나 없는 경우 유효성,그 점은 무엇인가?그것은 또한 더 빠르다.

이것을 고려하십시오:클래스가 있는 당신의 기본 클래스입니다.그것은 꽤 몇 가지 특성을 wan't 에서 사용하는 자식 개체.를 작성할 수 있습 get/set 기능을 각각에 대해,또는 당신은 설정할 수 있습니다.

나의 전형적인 예는 파일/스트림 처리기입니다.당신은에 액세스하려 처리기(예:파일기술자),그러나 당신이 숨기려는 다른 클래스입니다.그것의 방법보다 쉽게 쓰 set/get 기능에 대한니다.

일반적으로,그렇습니다.보호된 방법은 일반적으로 더 낫습니다.

에서 사용가의 수준은 단순 사용하여 주어진 보호 최종 변수에 대한 개체가 공유하는 모든 아이들의 클래스입니다.난 항상에 대해 조언 그것을 사용하는 기본 형식으로 또는 컬렉션은 이 계약은 불가능을 정의하는 사람들을 위해 형식입니다.

최근에는 올해 별도의 재료와 함께 할 기본과 원 컬렉션에서 물건을과 잘 형성됩니다.프리미티브와 컬렉션을 해야습니다.

또한,나는 시작한 때때로 노출에 공개 변수 회원 때 그들은 declaired 최종과 잘 형성되는 클래스는 너무 유연한(지 않고 다시 기본 형식이나 컬렉션도 있습니다).

이것은 몇 가지 바보 바로 가기로 생각,그것은 매우 심각하고 결정이 절대적으로 차이가 없이는 공개 최종 변 노출체 및 getter.

에 따라 달라집니다.당신이 원하는 경우 빠른 클래스는 데이터 보호되어야하고 사용할 보호 및 공개 방법이 있습니다.기 때문에 나는 당신을 생각해야한다고 가정 사용자가 파생되는 클래스에서 알고 있는 클래스 매거나 적어도 그가 읽기 당신의 매뉴얼에서 기능들을 재정의합니다.

는 경우 사용자가 엉망의 등 그것은 당신의 문제입니다.모든 악의가 있는 사용자를 추가할 수 있습 다음과 같은 라인을 재정의하는 경우 하나의 가상 메서드:

(C#)

static Random rnd=new Random();
//...
if (rnd.Next()%1000==0) throw new Exception("My base class sucks! HAHAHAHA! xD");
//...

할 수 없습니다 물개는 모든 클래스 이를 방지하기 위해.

물론 당신이 원하는 경우에 대한 제약 조건의 일부의 분야 다음 사용자 접근 기능 또는 속성이나 뭔가를 당신이 원하는 필드를 개인이 없기 때문에 다른 솔루션...

그러나 저는 개인적으로 좋아하지 않을 충실하 oop 원칙에서 비용이 든다.특히 만드는 속성을 가진 유일한 목적을 데이터 구성원 개인이다.

(C#):

private _foo;
public foo
{
   get {return _foo;}
   set {_foo=value;}
}

이 나 개인적인 의견입니다.

하지만 무엇이 당신의 상사가 필요(그가 원하는 경우 프라이빗 필드보다습니다.)

내가 사용하여 보호되는 변수/속성에는 기본 클래스 내에 계획으로 변화하는 방법입니다.는 방법으로,서브 클래스 전체에 액세스하여 그들의 상속변수,그리고 없(인위적으로 만들어진)오버헤드의를 통해 필요한 것입/세터를 액세스할 수 있습니다.예를 들어 클래스를 사용하여 기본적인 I/O 스트림;작은 이유가 있을 허용하지 않는 서브 클래스에 직접 액세스하는 기본다.

이는 정밀한 구성원에 대한 변수를 사용하는에서 직접 간단한 방법에 기본 클래스와 모든 하위 클래스.하지만 변수는 더 복잡하게 사용(예:액세스하는 부작용을 일으키는 원인이 됩니 다른 멤버에 클래스 내용),직접 액세스할 수 있는 변수가 적합하지 않습니다.이 경우에는,그것을 만들 수 있습니다 민간 및 공공/보호 getters/setters 제공될 수 있습니다 대신 합니다.예를 들어 내부 완충 메커니즘에 의해 제공되는 기본 클래스,어디에 액세스하는 버퍼에서 직접 서브 클래스키의 무결성 알고리즘을 사용하여 기본 클래스를 관리할 수 있습니다.

그것은 디자인 판단에 결정에 기초하여,어떻게 간단한 회원은 변수가,그리고 어떻게 될 것으로 예상되므로 미래에 버전입니다.

캡슐화는 좋지만,그것을 취할 수 있습니다.내가 본래 그 자신의 개인 방법에 액세스 해당 회원을 사용하여 변수만이터 구 방법이 있습니다.이것은 잔인한,이 경우 클래스를 신뢰할 수 없는 자신의 개인 방법으로 자신의 개인 데이터 수 있는 사람은 그것을 신뢰?

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