본문 바로가기
C#

[코드 최적화] 스파게티화 된 코드를 푸는 방법 2장 - 너무 길어진 switch에게는 Dictionary을 사용해보자.

by LemonCandy 2021. 8. 18.

이번 주제는 너무 길어진 switch에게는 Dictionanry를 사용해보자 입니다.

 

코드를 짜면서 switch문은 땔래야 땔수 없는 구문입니다. 하지만 이 Switch문에 조건이 너무 많아진다면? 그리고 그 case마다 처리가 복잡해져 길이가 길어진다면...? 우리가 추구하는 "한 화면에 들어오는"코드를 만족하기 어려운 상태가 될 것입니다.

 

이를 해결하는 방법으로는 Dictionary를 이용하여 흐름을 깔끔하게 정리하는 방법이 존재합니다.

먼저 예제 코드를 보겠습니다.

 

심플한 예제 코드입니다. Switch - Case 이외에 내용을 심도 깊게 알 필요는 없습니다.

 

위 코드의 내용은 별거 없습니다!

OnEventProcess() 함수로 NetworkEventID별로 어떤 처리를 해야하는지 각각 구분하기 위한 목적으로 Switch문을 사용합니다. 위의 Switch문은 단 3개의 case만을 사용함에도 불구하고 이미 한 화면을 넘으려고 하고 있습니다.

 

장기적으로 봤을때 저 내용들은 시간이 갈수록 걷잡을 수 없을만큼 길어지겠지요...

그럼 저 내용을 어떻게 정리해볼 수 있을까요?

 

여기서 우리는 고민을 해볼 필요가 있습니다.

OnEventProcess() 함수의 목적은 NetworkEventID마다 어떤 "명령"을 처리해야한다. 그 이상도 그 이하도 아닙니다. 각 case마다 서로 간에 커플링될만한 요소도 없다고 가정해봅시다. 그럼 OnEventProcess() 함수는 그 하위 switch 내부의 구체적인 내용을 알 필요가 있을까요?

 

위 스크린샷을 잘 보세요.

블러 처리를 했지만 OnEventProcess 함수의 "목적"을 이해하는데는 아무런 지장이 없으실겁니다.

우리는 이제 "목적"을 기준으로 저 코드를 정리 해볼것입니다.

 

첫번째로. Dictionary를 하나 만듭니다.

EnumNetworkEventID를 Key로 하며, Action을 Value로 하는 Dictionary.

이 Dictionary는 NetworkEventID 마다 어떤 Action(명령)을 처리해야하는지 명확하게 나타내줄 역할을 하게 될것입니다.

 

두번째로, 각 Case의 본문 내용 1,2,3을 Function화 해주세요.

Switch 내부의 Case 구문들을 모두 Function화 하였습니다.

 

세번째로 Function화 된 내용들을 Dictionary에 등록해주세요.

    void Awake()
    {
        InitCachedNetworkEventProcess();
    }

    private void InitCachedNetworkEventProcess()
    {
        _cachedNetworkEventProcess.Clear();
        _cachedNetworkEventProcess.Add(EnumNetworkEventID.NEI_FORCE_ENDGAME, OnEventForceEndGame);
        _cachedNetworkEventProcess.Add(EnumNetworkEventID.NEI_CHANGE_BATTLE_PHASE_ACK, OnChangeBattlePhaseAck);
        _cachedNetworkEventProcess.Add(EnumNetworkEventID.NEI_CHANGE_SUPPLY_PHASE_ACK, OnChangeSupplyPhaseAck);
    }

Dictionary의 특성을 이용하여 각 EnumNetworkEventID마다 해야하는 행동을 미리 지정하는 것입니다.

 

마지막으로 이제 OnEventProcess 함수를 다음과 같이 바꿔주세요.

    private void OnEventProcess(EnumNetworkEventID EventID, JSONNode nodeData_)
    {
        if (_cachedNetworkEventProcess.TryGetValue(EventID, out var func) == true)
            func();
    }

드디어 OnEventProcess는 자신의 "목적"에 맞는 코드만 남고 모든것이 사라졌습니다.

수십줄의 코드는 저마다 본연의 역할에 맞는 "함수"로 돌아갔습니다. 이제 더이상 OnEventProcess()는 구체적인 내용은 알 필요가 없는 것이지요. 또한 Function화 된 함수들이 길어져 핵심 코드를 읽는데 방해가 되는 경우에는 C#의 Partial Class의 성질을 이용하여 다른 파일로 옮겨두면 훨씬 더 목적에 맞는 관리를 할 수 있겠지요?

 

아주 길어진 Switch 코드는 위와 같은 방법을 통하여 코드를 깔끔하게 정리해보세요.

도움이 되셨기를 바랍니다. 감사합니다.