dngchn's [WPF]2017. 5. 31. 11:52

Collection을 노출하는 방법

Collection을 외부에 노출하는 작업은 종종 필요하고, 다양한 방법이 있겠지만 몇가지 이슈사항을 고려하여 아래와 같은 방법을 추천한다.


Example 1 -> 좋은 예

public class AddressBook
{
    private readonly List<Contact> contacts;

    public AddressBook()
    {
        this.contacts = new List<Contact>();
    }

    public IReadOnlyList<Contact> Contacts { get { return contacts; } }

    public void AddContact(Contact contact)
    {
        contacts.Add(contact);
    }

    public void RemoveContact(Contact contact)
    {
        contacts.Remove(contact);
    }
}

1. 위에서와 같이 IReadOnlyList<T> 또는 IReadOnlyCollection<T>를 이용하여 collection을 외부에 노출시킨다.

순서가 중요하면 IReadOnlyList<T>를 사용,

순서가 중요하지 않다면 IReadOnlyListCollection<T>를 사용.


2. Collection을 조작할 수 있는 메서드를 제공할 것.

이렇게 해야 collection 조작에 대한 컨트롤을 유지할 수 있다(여기저기 다른 곳에서 collection 조작 금지)

이러한 메서드들은 단순하게 collection을 조작하는 일 외에 추가적인 처리를 더할 수 있다(Add메서드에 유일성을 검사하기 위한 판단 추가 등).


3. IEnumerable<T>를 쓰지 말아라, collection을 노출하기 위한 목적이라면.

동작에는 문제 없으나, 성능적인 이슈가 문제 될 수 있음.

 IEnumerable<T>가 단순 collection이 아닌 query를 나타낸다면, 해당 구문 실행 시 마다, 중복되어 query문이 실행될 여지 있음.

* 이에 대한 경고를 'Resharper'에서는 "Possible multiple enumeration of IEnumerable"과 같이 주고 있음.



Example 2 -> 나쁜 예

// This example shows how you should not to expose a collection!
public class AddressBook
{
    public AddressBook()
    {
        Contacts = new List<Contact>();
    }
        
    // Property should not expose the concrete collection type and avoid providing a public setter.
    public List<Contact> Contacts { get; set; }
}

1. 위에서와 같이 구체적인 타입(Contact과 같이)으로 외부에 노출하지 말것.

collection의 타입을 변경해야 한다면 이는 의존성을 증가 시킨다.

외부에서 구체적인 타입의 collection을 얻을 수 있다면 직접 collection을 조작할 수도 있어 collection 조작에 대한 control을 잃어버릴 수 있다.


2. 외부에서 collection을 교체해버리도록 하지 말것.

외부의 코드는 collection의 타입(List or ...)을 고를 책임이 없어야 한다.



IReadOnlyCollection을 사용하면 외부에서 collection을 조작할 수 없다. 그러나 이 의미가 collection 자체가 더이상 변경될 수 없을을 뜻하지는 않는다. 만약 정말 collection이 변하지 말길 바란다면 Immutable Collection을 사용해라.


-끝.


* 참조: http://waf.codeplex.com/discussions/579918

Posted by dngchn