분류 전체보기 188

클린코드 6장 (객체와 자료 구조)

6장 - 객체와 자료 구조 흔히 필드를 private로 선언하고 getter, setter를 public으로 놓는데 이게 뭔 의미가 있을까? 저자인 로버트 C. 마틴도 `조회 함수와 설정 함수로 변수를 다룬다고 클래스가 되지는 않는다.` 라고 말한다. 그보다는 추상 인터페이스를 제공해야 한다고 말한다. 즉, 자료를 하나하나 공개하기보다는 추상적인 개념으로 묶어서 표현하는 것이 좋다. public interface FuelTank { double getFuelTankCapacity(); double getFuel(); } public interface FuelTank { double getPercentFuelRemaining(); } 즉, 위에꺼보다 아래꺼가 낫다. 개발자는 자료를 표현할 가장 좋은 방법을..

이론/설계 2021.05.10

클린코드 4,5장 (주석, 형식)

4장 주석 주석은 실패를 의미한다. 코드로 의도를 표현하지 못한 것을 만회하기 위해 주석을 사용한다. 즉, 원래는 주석 없이 코드로만 의도를 표현하는게 가장 이상적이다. 심지어 주석은 보통 나쁘다. 왜냐? 코드를 변경하면서 주석을 유지보수하기란 힘든 일이고, 결국 주석은 낡아지고 잘못된 정보를 드러내게 된다. 그럼에도 좋은 주석이 있다. 코드로 의도를 표현하는 것이 가장 이상적이지만 현실적으로는 힘든 경우가 많다. 다음은 좋은 주석의 예이다. 정보를 제공하는 주석 : 기본적으로는 함수나 변수의 이름에 정보를 담아야 한다. 그러나 시간을 나타내는 문자열의 포맷같은 정보는 유용할 수 있다. 의도를 설명하는 주석 : 프로그램의 의도가 아닌 코드를 작성한 저자의 의도는 타당하다. (저자의 의도를 코드에 담을 수..

이론/설계 2021.05.07

클린 코드 2,3장 (이름, 함수)

로버트 C. 마틴의 클린코드 2,3장을 정리 이름(22p~) 이름은 의도를 분명히 밝혀야 한다. 이름을 보고 존재이유, 수행 기능, 사용 방법을 알 수 있어야 한다. 오해를 불러올 수 있는 이름은 피해라.(24p) 쓸데없는 단어 붙이지 마라 : ~Info, ~Data 이런게 무슨 정보를 제공하는가? customer, customerInfo, customerData 는 관례 없이는 구분하기 힘들다. 읽는 사람이 차이를 알도록 이름을 지어야 한다. Manager, Processor... 등 도 마찬가지 타입을 인코딩하지 마라 : monsterList 는 그냥 monsters로 해라. 타입이 Dict로 바뀌면 어쩔껀가? 타입을 적는다고 해서 이득도 없다. 'm_'이런 접두어도 붙이지 마라 : IDE에서 색 다..

이론/설계 2021.05.02

클린 아키텍쳐

로버트 C. 마틴의 클린 아키텍쳐를 읽고... 12장부터 '대충' 요약 컴포넌트 컴포넌트는 배포할 수 있는 가장 작은 단위를 의미한다. (jar, dll 같은 파일) 컴파일형 언어에서는 바이너리 파일의 결합체, 인터프리터형 언어의 경우 소스파일의 결합체이다. 잘 설계된 컴포넌트라면 반드시 독립적으로 배포가능(=독립적으로 개발가능)해야한다. 어떤 클래스를 어느 컴포넌트에 포함시켜야 할까? 세 가지 원칙을 고려할 수 있다. REP (재사용/릴리스 등가 원칙) : 재사용 단위는 릴리스 단위와 같다. CCP (공통 폐쇄 원칙) : SRP의 컴포넌트 버전. 서로 다른 이유로 변경되는 클래스는 서로 다른 컴포넌트로 분리해라! CRP (공통 재사용 원칙) : 컴포넌트 사용자들을 필요없는 것에 의존하도록 강요하지 마라..

이론/설계 2021.04.25

Unity에서의 Null Comparison

Comparison to 'null' is expensive Rider 에디터에서 유니티 오브젝트의 Null 비교 '=='연산자를 통해 수행하려 하면 다음과 같은 안내가 나온다. 단순히 null을 비교하는데 왜 이런 안내가 뜰까?? 이유는 UnityEngine.Object가 비교 연산자를 오버라이드 했기 때문이다. UnityEngine.Object의 비교 연산자는 lhs나 rhs중 둘 중 하나만 null일 때, 나머지 하나가 '살아있는' 오브젝트인지 검사한다. 이 과정은 나름 시간이 소요되기에 라이더에서 저런 안내를 해주는 것이다. 그러면 UnityEngine.Object가 살아있음을 보장할 수 있다면 null비교를 더 빠르게 수행할 수 있지 않을까? 여러 방법이 있겠지만 대충 세 가지 방법을 생각해 볼..

C# - 관리 힙과 GC (2)

네이티브 리소스의 처리 네이티브 리소스 네이티브 리소스란 파일이나 커널 객체 같은 걸 말한다. 대부분의 타입들은 메모리만을 이용하지만 네이티브 리소스를 사용하는 애들(파일 핸들, 소켓) 같은 애들은 그렇지 않다. 이런 경우에 GC가 네이티브 리소스를 감싸고 있는 타입을 수거해 간다면 네이티브 리소스에 대한 누수가 발생하게 된다!! GC는 네이티브 리소스에 대해 알지 못하기 때문에 이에 대한 처리가 필요해 보인다. Finalization 파일, 네트워크 연결, 소켓, 뮤텍스 같은 네이티브 리소스를 감싸고 있는 타입은 finalization이란걸 지원한다. CLR은 GC가 이런 객체를 가비지 수집하는 과정에서 Finalize 라는 메서드를 호출하여 객체가 감싸는 네이티브 리소스를 정리할 기회를 준다. pub..

언어/C# 2021.04.03

C# - 관리 힙과 GC (1)

관리 힙 C#은 왜 관리 힙을 쓰나? 메모리 관리를 수동으로 해줘야 하는 C++의 경우 메모리 해제를 까먹어 메모리 누수가 발생하거나, 이미 해제한 메모리에 접근하여 메모리 손상이 발생하는 경우가 많고 이는 결국 버그나 보안 취약점으로 연결된다. 리소스 할당 CLR환경 하에서는 모든 객체가 관리 힙에 할당된다. 프로세스가 초기화되면, CLR은 관리 힙으로 쓸 주소 공간을 할당하고 다음 객체를 할당할 위치를 가리키는 포인터(이하 NextObjPtr)을 시작 주소를 가리키게 한다. 이 주소 영역이 가득 차면 CLR은 프로세스의 주소 공간이 사용될 때 까지 영역을 확대한다. new연산자 CLR에서 new연산자는, 필요한 용량을 계산한다. (특정 타입의 필드, 상속한 타입의 필드까지) - 여기에는 type ob..

언어/C# 2021.03.28

아키텍처 - 설계원칙 (SOLID)

SRP (단일 책임 원칙) 흔히 이걸 모듈이 단 하나의 일만을 해야 한다는 의미로 오인하기 쉬운데 그렇지 않다. (단, 함수는 단 하나의 일을 해야한다는 원칙이 있긴 한데 이건 설계원칙은 아니고 리팩토링할때나 쓰는 원칙) SRP의 진정한 의미는 '단일 모듈은 변경의 이유가 오직 하나뿐이어야 한다.' 이다. 다시 말하면 '단일 모듈은 그 모듈을 변경하려는 집단(액터)이 하나여야 한다.' 만약 한 집단의 수정사항을 반영한 것이 다른 집단의 작업에 영향을 끼칠 수 있다면 이것이 SRP를 위반한 사례라고 볼 수 있다. (이런 사례는 종종 형상관리툴에서 Merge를 발생시킨다.) 해결책은 무엇일까? 확실한 방법은 액터마다 데이터와 메서드를 분리하고 데이터는 별도의 클래스를 만들어 공유하는 방식이다. 그러나 이런 ..

이론/설계 2021.03.21

아키텍쳐 - 프로그래밍 패러다임

패러다임 프로그래밍에도 패러다임이 있다. 구조적 프로그래밍 객체지향 프로그래밍 함수형 프로그래밍 프로그래밍 패러다임은 프로그래머가 무엇을 할 지가 아니라 무엇을 하면 안 되는지를 말해준다. 위의 3가지 규칙은 프로그래머에게 goto문, 함수 포인터, 할당문을 뺏는다. 구조적 프로그래밍 goto문은 프로그램의 모듈을 분해하는 것을 방해한다. 만약 모듈을 분해할 수 없다면 분할 정복 기법의 사용이나 각각의 모듈을 테스트 하는데 어려움이 있을 것이다. 구조적 프로그래밍은 goto문의 사용을 제한함으로써 프로그래밍에서 테스트 가능한 단위를 작게 만들어 낸다. 이렇게되면 프로그래머가 각각의 컴포넌트, 모듈...등을 쉽게 테스트할 수 있다. 객체 지향 프로그래밍 흔히 객체 지향 프로그래밍의 요소로 캡슐화, 상속, ..

이론/설계 2021.03.09