디자인 패턴
17편
타입을 고치지 않고 타입마다 다른 일을 시킨다
동작을 하나 추가할 때마다 모든 클래스를 열지 않아도 됩니다. 대신 타입을 하나 추가할 때 모든 동작을 고쳐야 합니다.
감싸는 것은 같고 무엇을 바꾸는지가 다르다
어댑터와 퍼사드와 데코레이터는 셋 다 다른 것을 감쌉니다. 갈리는 것은 감싼 뒤에 인터페이스가 어떻게 되느냐입니다.
전부 검사하지 않으려면 미리 나눠 둔다
적 500마리가 서로 부딪혔는지 보려면 12만 번을 비교해야 합니다. 공간을 칸으로 나눠 두면 같은 칸과 이웃 칸만 보면 됩니다.
같은 값을 인스턴스마다 복제하지 않는다
적 2000마리가 각자 들고 있는 이름과 아이콘과 기본 스탯은 전부 같은 값입니다. 하나만 두고 모두가 가리키면 됩니다.
오브젝트 풀은 언제 손해인가
풀링이 항상 이득이라는 통념을 실측으로 확인해봤고, 손해가 나는 구간이 분명히 있었다.
바뀌었다는 사실만 적어 두고 계산은 미룬다
한 프레임에 열 번 바뀌어도 화면에 나가는 것은 마지막 하나뿐입니다. 앞의 아홉 번은 계산해서 곧바로 버려집니다.
상태를 하나로 두면 화면은 그 상태의 결과가 된다
값이 흩어져 있으면 화면이 이상할 때 그 순간을 재구성할 수 없습니다. 상태를 하나로 모으고 바꾸는 길을 하나로 막으면 재현과 되돌리기가 따라옵니다.
값을 미는 대신 흐름을 잇는다
MV(R)P 는 MVP 의 이벤트 연결을 스트림으로 바꿉니다. 구독 해제가 자동이 되고 값 여러 개를 합치는 일이 한 줄이 됩니다.
무엇을 쪼개느냐가 아니라 누가 누구를 아는가
셋 다 데이터와 화면을 나누는 이야기입니다. 다른 것은 나누는 방법이 아니라 나눈 뒤에 남는 참조의 방향입니다.
new 를 부르는 자리를 한 곳으로 모은다
인터페이스로 갈아 끼울 수 있게 만들어 놔도 new 가 코드 곳곳에 흩어져 있으면 구체 타입 이름은 그대로 남습니다.
호출을 객체로 만들면 저장할 수 있게 된다
메서드는 부르고 나면 아무것도 남지 않습니다. 부르라는 지시를 객체로 만들어 두면 되돌리기, 기록, 리플레이, 전송이 한꺼번에 딸려 옵니다.
구조는 같고 누가 바꾸느냐가 다르다
전략과 상태는 코드만 보면 거의 구분이 안 됩니다. 갈리는 지점은 하나입니다. 다음에 무엇을 쓸지 밖에서 꽂아 주느냐, 자기가 정하느냐.
상태가 하나 늘면 조건은 하나만 늘지 않는다
bool 플래그는 있을 수 없는 조합까지 만들어 냅니다. enum 으로 한 번 정리되지만 switch 가 여러 곳에 흩어지면서 다시 무너집니다.
발신자를 지우면 추적할 단서도 같이 지워진다
이벤트 버스는 알리는 쪽과 듣는 쪽이 서로를 모르게 만듭니다. 결합은 더 느슨해지지만 이 이벤트를 누가 보냈는지 찾는 일이 어려워집니다.
버튼은 누가 듣고 있는지 몰라도 된다
반응이 늘 때마다 버튼을 고치는 대신 반응이 스스로 등록하게 합니다. C# 의 event 가 이미 그 구조라, 배우는 게 아니라 이름을 붙이는 일에 가깝습니다.
무엇을 쓸지는 부르는 쪽이 아니라 등록하는 쪽이 정한다
서비스 로케이터는 싱글톤에서 전역 접근은 남기고 구현만 떼어냅니다. 갈아 끼울 수 있게 되는 대신 컴파일 에러가 런타임 에러로 밀립니다.
어디서든 부를 수 있다는 것은 어디서나 묶인다는 뜻이다
싱글톤은 유일성과 전역 접근 두 가지를 한꺼번에 보장합니다. 편한 것은 두 번째인데 대가도 전부 두 번째에서 나옵니다.