프로그래밍 집단이 추구하는 가치

프로그래밍 2016.01.02 23:48 by 에그

얼마 전에 코드 리팩토링을 하던 중 아래와 같은 코드를 작성했습니다(기억나는대로 적은지라 정확히 일치하지 않을 수 있습니다.).

// SkillDataManager.cs
public class SkillDataManager
{
    public static SkillDataManager _Instance { get; private set; }
    private static object _sync = new object();

    private SkillDataManager() { }

    public static void Create()
    {
        lock(_sync)
        {
            if (_Instance == null)
            {
                _Instance = new SkillDataManager();
            }
            else
            {
                // 인스턴스 이미 있음 오류처리
            }
        }
    }
}

// ItemDataManager.cs
public class ItemDataManager
{
    public static ItemDataManager _Instance { get; private set; }
    private static object _sync = new object();

    private ItemDataManager() { }

    public static void Create()
    {
        lock (_sync)
        {
            if (_Instance == null)
            {
                _Instance = new ItemDataManager();
            }
            else
            {
                // 인스턴스 이미 있음 오류처리
            }
        }
    }
}

인스턴스가 하나만 있어야 하는 자료 관리자여서 싱글톤 패턴을 적용한거죠.

얼마 후에 다른 프로그래머와 이야기하다가 이 싱글톤을 제네릭으로 바꾸면 어떨까 하는 이야기가 나왔습니다. 복붙할 코드가 많고 코드 양도 길어지기 때문이죠. 위 코드만 봐도 클래스 이름만 다르고 공통 코드가 많긴 합니다.


사실 불가능한건 아닙니다. 실제로 예전에는 제네릭 싱글톤 코드도 만들었습니다.

제가 다시 지워버렸죠!

// Singleton.cs
public class Singleton<T> where T : class
{
    public static T _Instance { get; private set; }
    private static object _sync = new object();

    public static void Create()
    {
        lock (_sync)
        {
            if (_Instance == null)
            {
                // 리플렉션으로 T타입 생성자 찾아 강제호출
                Type t = typeof(T);
                ConstructorInfo[] ctors = t.GetConstructors();
                if (ctors.Length > 0)
                {
                    // 생성자 없음 오류처리
                }
                _Instance = (T)Activator.CreateInstance(t, true);
            }
            else
            {
                // 인스턴스 이미 있음 오류처리
            }
        }
    }
}

// SkillDataManager.cs
public class SkillDataManager : Singleton<SkillDataManager>
{
    private SkillDataManager()
    {
    }
}

// ItemDataManager.cs
public class ItemDataManager : Singleton<ItemDataManager>
{
    private ItemDataManager()
    {
    }
}

싱글톤 클래스는 외부에서 생성자를 이용한 인스턴스 생성을 막아야 합니다. private 생성자가 필요한거죠.

하지만 제네릭 싱글톤을 사용하려면 인스턴스 생성을 위해 외부에서 생성자 호출이 필요합니다. 즉, 위 코드와 같이 리플렉션을 이용해 강제로 생성자를 호출해야 합니다.


제네릭 싱글톤을 지우고 복붙 싱글톤을 사용할 때 제가 중요하게 여겼던 가치는 아래와 같습니다.


- 하지말라는건 하지 말자.

private 은 클래스 외부에서는 호출되지 않음을 명시하는 키워드다. private 이지만 외부에서 호출된다는 예외가 늘어날수록 코드를 믿을 수 없게되고 확인하는 비용이 발생한다.


하지만 제네릭 싱글톤에도 분명히 가치가 존재합니다.


- 개발 생산성이 높아진다.

복붙 코드가 줄어 실수의 여지와 코드 양이 줄어든다. 읽기 쉬워진다.


양쪽 모두가 분명히 타당한 이유를 가지고 있습니다. 나름의 장점도 있구요. 이런 경우 어떤 방법을 선택해야 할까요?

이런저런 이야기를 나눈 끝에 제가 내린 결론은 이렇습니다.


"집단이 추구하는 가치와 더 부합하는 가치를 선택한다."


빠른 출시를 원한다면 생산성을 중시할 수 있습니다.

외부 공개를 목적으로하는 라이브러리라면 재사용성이나 코딩 컨벤션의 준수에 높은 가치를 둘 수 있습니다.

라이브 서비스라면 버그 발생 방지가 가장 높은 가치일 수 있습니다.


이러한 집단의 가치를 구성원들이 공유하게 되면 의사 결정에 큰 도움이 됩니다.


집단의 가치가 "빠른 릴리즈"라면, 기존과 약간만 다른 임시 기능을 만들기 위해 공통점을 추상화 하는 과정 대신 복붙을 사용하는 판단을 내릴 수 있을 것입니다. 또한 그 코드를 보는 다른 프로그래머들도 집단의 가치가 "당장 내일 업뎃해야하는 설날 이벤트 패치"임을 알고 있다면 이 복붙 코드의 의도를 파악해 코드 퀄리티에 괴로워하는 상황을 줄일 수 있겠죠.


이때 필요한 것이 집단이 추구하는 가치를 결정하기 위해 합의하는 과정이라고 생각합니다. 구성원들이 각자가 중요시하는 가치를 공유하고, 이 프로젝트가 어떤 가치를 추구할 것인지 결정하는 것이죠.

이를 위해서는 동기 사이, 팀장과 팀원 사이, 갓 들어온 신입과 프로젝트 전반을 꿰뚫고 있는 베테랑 사이에서 자유로운 토론과 대화를 통해 생각을 주고받을 수 있는 분위기가 중요할 것입니다.


싱글톤 이야기로 돌아오면, 다시 제네릭 싱글톤을 이용하기로 결정했습니다.

저희 프로젝트는 생산성이라는 가치가 중요하다는 결론을 내렸기 때문입니다. 외부에 공개할 코드도 아니니 private 생성자가 강제 호출 가능된다는 점만 프로그래머끼리 공유하면 되고, 자료 관리자들은 초반에 일괄적으로 생성되므로 리플렉션을 이용할 때의 속도 문제도 크게 문제되지 않을 것이라는 이유도 있습니다.


타인과 교류 없이 혼자 작업에 몰두하는 이미지가 강한 프로그래머라는 직업이, 사실은 어느 직업보다도 동료와의 의견 공유를 필요로 하는 일이었구나 하는 생각이 드는 경험이었습니다.

신고
BlogIcon 잉여차 2016.01.03 21:34 신고

하나 궁금한 건, 굳이 destroy 할 필요가 없거나 create 시점을 명확히 정해야 하는 요소가 아니라면 object lock을 걸고 싱글톤 생성을 시도하는 것보다는 위 코드에서 선언부에 new object() 하듯이 new 싱글톤 클래스()를 하는 접근이 어떤가 싶기도 해서 'ㅅ'ㅋㅋ Java에서는 구조상 복잡한 JVM API를 사용할 게 아니면 그런 식으로 권고를 많이 하거든.

BlogIcon 에그 2016.01.06 09:08 신고

너가 말한 그대로다 ㅋㅋ 위 예제에서는 데이터 관리자여서 생성삭제가 명확할 필요가 있어서 저렇게 했음. 실제 프로젝트에서 쓰는 이름도 그냥 싱글톤이 아니라 DataSignleton 일세 ㅋㅋㅋ

You logged-in!
Nav

티스토리 툴바