이 포스팅은 POCU 아카데미의 '개체지향 프로그래밍 및 설계(Java)' 동영상 강의를 학습하고 정리한 내용입니다.
제 의견이 추가되어 강의 내용과 포스팅 내용이 일치하지 않을 수 있다는 점 미리 말씀드립니다.
이 글에서는, 강의를 들으면서 알게된 코딩 스탠다드를 정리하였습니다. 추후 몸에 익히면 좋을 내용들이라고 생각합니다.
생성자로 초기화를 해야하는 이유
- 개념상의 문제 : 생성자는 개체를 생성하는 공장 역할을 한다. 공장에서 찍어 나온 물건이 비어 있다는 것은 말이되지 않는다.
- 후조건의 문제 : 함수에 “선조건과 후조건”이 적용되는 것처럼, 생성자도 적용되어야 한다. 생성자는 어떤 개체를 생성할 때, 생성되자마자 유효한 것을 보장하기 위한 함수이다. 따라서 생성자는 “개체의 상태는 개체 생성과 동시에 유효하다”라는 후조건을 만족해야 한다.
- 사용자를 고려 : 사용자(내가 만든 클래스를 사용하는 사람)는 클래스에 있는 어떤 멤버 변수를 초기화해야 하는지 or 어떤 값으로 초기화해야 하는지 알지 못할 수 있다.
결론 : 생성자는 개체를 만들어주는 계약이다.
호출자와 함수의 분명한 책임 분리
호출자가 함수 속이 어떻게 작동하는지 몰라도 정상적으로 사용할 수 있도록, 함수는 잘 정의되어야 한다. 이 책임의 분리는 함수 시그내처, 선조건, 후조건 등으로 확실히 정의되어야 한다. 초보자들은 종종 함수가 잘못되었을 때, 함수가 반환하는 값을 호출자에서 변경하여 사용하는 실수를 범한다고 한다. 함수는 함수명에서 지칭한 동작을 수행해야 한다. 따라서, 함수가 잘못되었으면 함수를 변경해야 한다. 호출자에서는 함수 내부 동작은 신경쓰지 말아야 한다.
setter 베스트 프랙티스
- 멤버 변수의 접근 제어자는 private으로 한다. 대부분의 경우 모두 private이며, 정보 숨기기를 적용한다.
- 새 개체는 생성과 동시에 유효하도록 한다. 개체는 살아있는 동안 언제나 유효한 상태로 만들어야 프로그래머의 실수를 막을 수 있다. 생성자를 통해서 정상적인 개체가 생성되도록 강제할 수 있다.
- getter는 자유롭게 추가한다. 사용자가 알 필요 없는 정보는 보여주지 않는 게 정석이다. 그러나 보여줘도 큰 문제는 없으니 getter는 보통 자유롭게 추가한다. 다만, 어떤 개체의 래퍼런스를 반환할 때는 문제가 될 수 있다.
- setter는 충분히 고민하고 추가한다. 이상적인 개체의 상태 수정법은, 사용자가 어떤 동작을 지시했을 때 동작의 결과로 개체 안에 있는 어떤 상태가 바뀌게 해야 한다. 즉, 개체 스스로 자신의 상태를 변경해야 한다. 단, 언제나 그럴 수는 없기에 많이들 허용하곤 한다. 중요한 점은 개체가 불확실한 상태로 되는 경우를 최대한 막아야 한다는 것이다.
OO 설계에서 처음 만나는 난관
한번에 올바른 설계를 만들려고 해서 어려움을 겪는것이다. 애초에 이렇다 할 정답은 존재하지 않는다. 여러번 다시 고치는 것이 오히려 쉽다. 따라서, 설계를 엎는 것은 흔한 일이니까 너무 걱정하지 말자.
개체 모델링에서 흔히 저지르는 실수
실세계의 상태와 동작을 모두 클래스에 넣으려고 해서는 안된다. 소스코드는 작성한 순간부터 유지보수의 대상이다. 개발하다 보면 코드를 여러번 고치게 되므로, 사용하지 않는 코드는 쓸데없는 유지보수 비용의 증가를 야기할 뿐이다. 단순하게 시작해야 한다. 코드는 필요한 시점에 추가하면 된다. 보통 내가 처음에 내린 가정은 거의 틀린다. 훌륭한 프로그래머는 이것을 알기 때문에 단순하게 만든 뒤 살을 붙인다. 고로, 필요없는 것은 넣지 않는다.
OO의 사고방식
OO세계의 물체는 어느정도 자기 주관을 가진 주체이다. 주체(개체)들은 서로 상호작용해야 한다. 호출자 코드에서 개체의 동작을 직접 처리하는 것은 구조체 사고방식이다.
코드 유연성은 양날의 검이다.
- 유연성 높음 : 성능 낮음, 가독성 낮음, 재사용성 높음
- 유연성 낮음 : 성능 높음, 가독성 높음, 재사용성 낮음
OOP 공부 가이드라인
- 프로그래머의 기본기를 갖추는게 우선이다. 프로그래머의 기본자세는 “읽기 명확한 코드 만들기(가장 중요)”, “실수를 저지르기 어려운 코드 만들기”, “문제를 해결하는 코드 만들기”, “문제가 생기면 디버깅 하기”이다.
- 필요에 따라 유연성을 키우는 법을 배워 나가기 : 코딩하다가 유연성이 필요해 보이는 것 같은 의문이 들 때, 유연성을 높이는 시도를 해야 한다. 그 전에는 기본자세가 가장 중요하다. 유연성은 필요하면 만들고, 필요없으면 안 만들어야 한다.
디자인 패턴 공부법
(기본기)내 코드가 정확히 어떻게 동작하는지 이해될 때까지는, 디자인 패턴을 바로 쓸 생각은 하지 말아야 한다. 디자인 패턴은 만능이 아니다. 프로그래밍을 잘 못하는 사람이 디자인 패턴을 익힌다고 해서 더 잘해지지 않는다. 아직 충분한 문제를 접하지 않은 상태이며 문제 해결방법도 손에 익지 않았기 때문에, 잘못된 패턴을 사용할 가능성이 존재한다. 나의 모자란 실력을 그럴싸한 것으로 숨기려 해서는 않된다.
실용적인 인터페이스 사용법
기본적으로는 클래스를 사용한다. 인터페이스는 함수 포인터와 같은 대상이 필요하거나, 다형성 있는 다중 상속이 필요한 경우에만 사용해야 한다. 다만, 내 클래스에 의존하는 코드들을 쉽게 바꿀 수 없는 상황인 경우, 변화에 대비하기 위해 인터페이스를 사용하여 커플링(결합도)을 줄인다.
'객체지향' 카테고리의 다른 글
[POCU-OOP] 디자인 패턴 (0) | 2023.12.24 |
---|---|
[POCU-OOP] 개체지향 프로그래밍 특성(OOP의 7대 특성) (2) | 2023.12.23 |
[POCU-OOP] 개체지향 프로그래밍의 필요성 (2) | 2023.12.23 |