2012-05-22 3 views
0

(무엇을 출력이 비어 있지 않은 경우 목록) :이런 방식으로리스트를 수정하는 것은 나쁜 습관입니까? 클래스 A에서

private List<int> _myList = new List<int> 
public List<int> MyList {get{return _myList;} set{_myList = value;}} 

클래스 B에서 :

public bool MyClassBMethod(stuff) 
{ 
    //stuff 
    try{ 
      something 
    } 
    catch(Exception){ 
     ClassA.MyList.Add(stuff); 
     return false; 
    } 
    return true; 
} 

이 나쁜 연습 같은 목록을 편집 할 수 있나요? 아니면 괜찮은가요?

편집 : 메소드가 다른 것을 반환해야하는 경우 (bool, object, string 등)에만 목록에 추가합니다.

+0

나에게 잘 보입니다. 무슨 상관이야? – jrummell

+0

"이 같은"무엇을 의미합니까? 다른 반에서 온거야? 부동산을 통해? Add 메서드를 통해? –

+0

클래스 A는'public static' 클래스입니까? 아니면 클래스 B의 MyList에 어떻게 접근하고 있습니까? –

답변

2

일반적으로 클래스는 자체 내부 상태를 관리해야합니다. 이와 같은 회원에게 공개적으로 접근 할 수있게되면 기본적으로 클래스 A가 해당 국가의 책임을 포기하고 있음을 알 수 있습니다. _myList에 포함 된 내용은 언제든지 변경할 수 있기 때문에 가정 할 수 없습니다.

좋은지 아닌지는 사용자의 의도에 따라 다르지만 실제로는 디커플링 및 캡슐화와는 반대되는 개념입니다. 다시 말하지만, 당신이 을 원한다면, 디커플링과 캡슐화는에 달려 있습니다.

더 나은 질문은 클래스 A와 B 사이의 어떤 종류의 디커플링이 디자인에 가장 유익한지를 결정한 다음 노출 할 멤버와 방법을 결정할 수 있습니다.

0

이것은 꽤 일반적인 관행입니다. 그렇게 일반적이지 않은 것은 공개를하는 것입니다. 비공개로 설정하고 A constructor에서 목록을 초기화하면 모두 설정됩니다.

public ObservableCollection<int> MyPublicList {get; private set;} 

WPF는 이와 비슷한 선언으로 가득합니다.

2

일반적으로 그렇게해서는 안됩니다.

클래스의 클라이언트에게 매우 큰 인터페이스를 제공하므로 모든 상황에서 클래스가 작동하는지 테스트하기가 어렵습니다. 기대하지 않을 때 누군가 가치를 제거하면 어떻게됩니까? 아니면 그들이 범위를 벗어난 값을 추가한다면? List에서 메서드를 호출 할 때 유효성을 검사 할 수 없으므로 잘못된 데이터가 어디서 왔는지 추적하기가 어려울 때 나중에 갑자기 클래스가 갑자기 중단 될 수 있습니다.

클래스의 Add을 호출하고 목록을 비공개로 유지하는 클래스에 Add 메서드를 사용하는 것이 좋습니다. 그런 다음 클라이언트가 수행하는 작업을 제어하고 사용해야하는 기능 (그리고 테스트 한 기능) 만 공개 할 수 있습니다.

+1

전혀 동의하지 마십시오. 이것은 .Net 프레임 워크에서 목록과 상호 작용하는 가장 일반적인 방법입니다. –

+0

@SoMoS : 'List '을 공개 속성으로 제공하는 .NET 프레임 워크의 클래스 예제를 제공 할 수 있습니까? –

+0

WPF 관찰 가능한 컬렉션. 당신은 항상 이런 식으로 그들을 보여줍니다. –

0

항상 그렇습니다. 목록이 클래스 외부에서 편집하려는 경우 (해당 클래스의 인터페이스 일부 임) 일반 목록 작업이 모두 허용되면 정상입니다. 작업의 하위 집합 만 허용되는 경우 모든 제약 조건을 적용하는 사용자 지정 목록 (또는 목록 주위의 래퍼)을 사용하십시오. 예를 들어 목록이 클래스 외부의 읽기 전용이어야하는 경우 클래스 외부에 ReadOnlyCollection 래퍼를 제공 할 수 있습니다. 데이터 무결성을 강화하는 데 모든 것이 필요합니다.

0

목록이 공개되는지 여부에 관심이 있는지 여부에 따라 다릅니다. & 공개 형식의 구체적인 유형에 액세스하면 구현 세부 사항이 노출되고 클래스와 해당 소비자 간의 결합이 증가합니다. 또한 구현 세부 사항이 더 이상 올바르게 캡슐화되지 않아 데이터 일관성을 적용 할 수있는 기회가 ClassA으로 제한됩니다.

가끔은 완벽하게 받아 들일 수 있습니다. 가끔은 그렇지 않습니다.

개체 모델이 벙어리 인 경우 허용 될 수 있습니다. 바보처럼, 나는 그것이 단지 데이터를 포함한다는 것을 의미한다. 이와 같은 상황은 JSON/XML을 객체로 파싱 할 때 자주 발생합니다. 즉, 데이터가 미러링되도록 구성되며, 동작은별로 중요하지 않으므로 문제가되지 않습니다. 작은 코드베이스에서 해킹을하거나 변경의 범위가 제한되어 있거나 동작이 거의 없다면 더 쉽게 수용 할 수 있습니다.

나는 보통 피하고 싶다.

먼저 ClassA의 목록에 추가하는 항목은 소수이어야한다고 가정합니다. AddItem() 메서드를 작성하면이 확인을 쉽게 적용 할 수 있지만 목록이 공개 된 경우 효과적으로 수행하는 것이 훨씬 더 어려워집니다.

두 번째로 목록을 사전으로 변경하기로 결정했다고 가정 해보십시오. 이전에 ClassA의 구현 세부 정보를 사용했기 때문에 호출 코드 사이트 (ClassB, 하나)를 깨뜨릴 수 있습니다. 대신 AddItem()RemoveItem() 또는 ClassA에 대해 비슷한 메서드를 만든 경우 ClassB은 내부 구현이 집합, 사전 또는 목록인지 여부에 상관 없으며 변경이 이루어지면 중단되지 않습니다.

'점으로 물건 넣기'(예 : blah.List[3].GetProduct(3).Reviews.First())와 관련된 지침은 이름이 The Law of Demeter입니다. 데메테르의 법칙의

두드러진 점은 다음과 같습니다

기본적인 개념은 주어진 객체가 구조 또는 (하위 구성 요소 포함) 무엇의 특성에 대해 가능한 한 적은 을 가정해야한다는 것입니다.

코드를 더 작성해야하지만 변경 사항을 보완해야합니다.

관련 문제