2009-05-21 2 views
0

단순히 테스트를 직접 작성하는 것이 아니라 사람들의 의견에 호기심이 많아서 ... ...게터를 통해 비공개 목록에 직접 추가 할 수 있습니까?

나는 비공개리스트를 가지는 클래스 공개 getMyList() 메소드를 통해 해당 비공개 목록에 추가하려고합니다.

이렇게 ...이 작업을 수행 할 예정입니까?

public class ObA{ 
private List<String> foo; 
public List<String> getFoo(){return foo;} 
} 

public class ObB{ 
    public void dealWithObAFoo(ObA obA){ 
    obA.getFoo().add("hello"); 

    } 
} 

답변

4

네, 그게 정상적으로 작동합니다 - 이것은 대개 나쁜 일입니다. 이는 참조을 컬렉션 객체가 아닌 컬렉션 객체에 실제로 반환하기 때문입니다.

컬렉션에 대한 진정한 읽기 전용 액세스를 제공하려는 경우가 종종 있습니다. 이는 대개 반환하는 것을 의미합니다 컬렉션 주위에 읽기 전용 래퍼. 반환 형식을 컬렉션에서 구현 한 읽기 전용 인터페이스로 설정하고 실제 컬렉션 참조를 반환해도 많은 보호가 제공되지 않습니다. 호출자는 "실제"컬렉션 유형으로 쉽게 캐스팅 한 다음 문제없이 추가 할 수 있습니다.

+0

감사합니다. 내 시나리오에서, ObA는 DTO입니다. 저는 서비스 클래스를 통해 멤버 중 한 명을 추가하고 있습니다 ... DTO를 가능한 한 무료로 동작시키고 싶다고 가정 할 때 선호하는 접근 방식은 무엇입니까? 기본적으로 비즈니스 로직이없는 더미 데이터 보유자가되고 싶습니다.) –

+0

음 ... 나는 그게 좋겠다고 생각했다.나는 개인적으로 거짓 데이터 보유 자의 문제로 선택의 여지가 없다고 개인적으로 염려 스럽다. –

+0

* 정말로 "바보 같은"클래스 인 경우, 모든 클라이언트는 컬렉션이 잘 될지 모른다는 것을 * 알 수있다. 다른 발신자가 수정 한 경우 그대로 사용하는 것이 좋습니다. "이 속성은 배킹 컬렉션에 대한 직접적인 참조를 반환합니다.이 참조를 통해 변경 한 내용은 다른 호출자가 볼 수 있습니다." –

2

실제로 좋은 생각은 아닙니다. 당신이 즉석에서 읽기 전용 버전을 제공 할 수없는 경우 당신은이 일에 대해 의견을 원하는 경우

public class ObA{ 
    private List<String> foo; 
    public List<String> getFoo(){return Collections.unmodifiableList(foo);} 
    public void addString(String value) { foo.add(value); } 
} 
+0

나는이 접근법을 좋아한다. 감사! –

+0

필자는 정말로 의존한다고 생각합니다. 대개 동의하지만, 때로는 캡슐화의 방식으로 많은 노력을하지 않는 진정으로 바보 같은 DTO를 갖는 것이 의미가 있습니다. –

+0

가능한 한 DTO의 경우에도. Joshua Bloch (또는 Brian Goetz?)가 말했듯이, 정말로 좋은 이유가 없다면, 객체를 변경 불가능하게 만드십시오. 물론 특별한 경우는 setter와 getter가있는 Java Bean 객체입니다. 그러나 그 외 ... 모든 객체를 변경 불가능하게 만들거나 가변성을 수행하는 메소드를 제공하십시오 (이 경우 전체 제어 권한이 있어야합니다). –

1

, 내가 getFoo() 전화를 제거 할 것 ... 복사본을 만들고, 밖에서 가변 멤버를 게시하지 마십시오 add(String msg)remove(String msg) 메서드 (또는 노출하고자하는 다른 기능)를 ObA에 추가하십시오

+0

아드리안은이 답을 가지고 펀치를 때렸지 만 입력 할 때 그 일이 일어 났는지는 알지 못했기 때문에 어쨌든 투표를하고 있습니다 :) –

+0

물론 ObA.remove (String value) 또는 foo를 조작하는 다른 원하는 메소드 ... –

1

컬렉션에 대한 액세스 권한 부여는 내 경험에 항상 나쁜 것으로 보입니다. 주로 퇴출 후에는 제어 할 수 없기 때문입니다 . 나는 그들을 포함하고있는 클래스 밖에서 컬렉션에 직접 접근하는 것을 허용하지 않는 습관을 택했다.

이 주된 이유는 거의 모든 종류의 비즈니스 로직이 데이터 컬렉션에 첨부되어 있다는 것입니다. 예를 들어, 추가 검증 또는 언젠가는 밀접하게 관련된 두 번째 컬렉션 .

당신이 말하는 것처럼 액세스를 허용하면 미래에 이와 같이 수정하는 것이 매우 어려울 것입니다.

아, 또한 종종 저장하는 객체에 데이터를 조금 더 저장해야하는 경우가 종종 있습니다. 따라서 새 객체 (컬렉션이있는 "컨테이너"내부에서만 알려짐)를 만들고 나는 그것을 컬렉션에 넣기 전에 그 안에 오브젝트를 넣었습니다.

컬렉션을 잠근 상태로 두었다면 이는 사소한 리팩터링입니다. 컬렉션을 잠근 상태로 유지하지 않은 곳에서 작업 한 경우에 어떤 어려움이 있었는지 상상해보십시오.

1

Foo에 추가 및 제거 기능을 지원하려면 다음과 같은 방법을 제안합니다. addFoo() 및 removeFoo(). 이상적으로는 필요한 각 기능에 대한 메소드를 작성하여 getFoo를 함께 제거 할 수 있습니다. 이렇게하면 호출자가 목록에서 수행 할 함수를 명확히 알 수 있습니다.

관련 문제