#개발자, #노개북, #코딩, #클린코드
변수를 비공개로 정의 하는 이유가 있다. 남들이 변수에 의존하지 않게 만들고 싶어서이다. 충동이든 아니든 변수타입이나 구현을 맘대로 바꾸고 싶어서이다. 그렇다면 어째서 수많은 프로그래머가 조화 함수와 설정함수를 당연하게 공개해 비공개 변수를 외부에 노출할까?
두 클래스 모두 2차원 점을 표현함. 한 클래스는 구현을 외부로 노출, 한 클래스는 구현을 완전히 숨긴다.
추상적 | 구체적 |
---|---|
접근정책을 강제함 | 직교좌표계 사용. |
개별적인 좌표읽기 | 개별적인 좌표읽기 |
설정시 두 값을 한번에 설정해야함 | 좌표 읽고, 설정까지 강제함 |
구현 은닉 | 구현 노출(조회,설정함수 제공) |
구현을 감추려면 추상화가 필요하며 , 추상인터페이스를 제공해 사용자가 구현을 모른 채 자료의 핵심을 조자갈 수 있어야 진정한 의미의 클래스다.
자료를 세세히 공개하기보다 추상적인 개념으로 표현하는것이 좋다. 개발자는 객체가 포함하는 자료를 표현할 가장 좋은 방법을 심각히 고민해야한다.
객체는 추상화 뒤로 자료를 숨긴채 자료를 다루는 함수만 공개한다. 자료구조는 자료 그대로 공개하며 별다른 함수는 제공하지 않는다. 두 정의는 본질적으로 상반된다. 객체와 자료구조는 근본적으로 양분된다.
절차적인 코드 | 객체지향 코드 | |
---|---|---|
함수 | 쉬움 | 어려움(모두 고쳐야함) |
클래스 | 어려움 | 쉬움 |
자료구조 | 어려움(모두 고쳐야함) | 쉬움 |
객체지향 코드에서 어려운 변경은 절차적인 코드에서 쉬우며, 절차적인 코드에서도 그 반대이기도하다. 복잡한 시스템을 짜다보면 새로운 함수가 아니라 새로운 자료타입이 필요한 경우가 있는데, 이때는 클래스와 객체 지향 기법이 가장 적합하다. 새로운 자료 타입이 아니라 새로운 함수가 필요한 경우도 생긴다. 이때는 절차적인 코드와 자료구조가 좀 더 적합하다.
객체는 자료를 숨기고 함수를 공개한다. 즉 객체는 조회수 함부로 내부구조럴 공개하면 안된단 의미인것이다. 좀 더 정확히 디미터 법칙은 '클래스 C의 메서드 f는 다음객체의 메서드만 호출한다고 주장한다.'
위 객체에서 허용된 메서드가 반환하는 객체 메서드는 호출하면 안된다. 다시말해, 사람을 경계하고 친구랑 놀란 의미인것이다.
때때로 절반은 객체, 절반은 자료구조인 잡종구조가 나온다. 잡종구조는 중요한 기능을 수행하는 함수도 있고, 공개변수나 공개 조회/설정 함수도 있다. 그리고 비공개 변수를 그대로 노출하기도 한다. 덕분에 절차적인 프로그래밍 자료구조 접근 방식처럼 비공개 변수를 사용하고픈 유혹에 빠지기 쉽다.
잡종구조는 함수는 물론이고 새로운 자료구조마저 추가하기 어렵다. 양쪽의 단점이 모여놓는듯 한 구조가 된다. 그러므로 잡종구조는 되도록이면 피하는것이 좋다. 너무 어중간하다.
자료구조체의 전형적인 형태는 공개변수만 있고, 함수가 없는 클래스다. 이런 자료 구조체를 자료 전달 객체라고 부른다. 자료전달객체(Data Transfer Object) 는 굉장히 유용한 구조체다. 특히 데이터베이스와 통신하거나 소켓에서 받은 메세지의 구분을 분석할때 아주 유용하다. 흔히, 데이터베이스에서 저장된 가공되지않은 정보를 애플리케이션 코드에서 사용할 객체로 변환하는 일련의 단계에서 가장 처음으로 사용하는 구조체이다.
자료전달객체의 특수형태다. 대게 비공개 변수에 조회/설정 함수가 있는 자료구조이지만, 거기에 save와 find 같은 탐색함수도 제공한다. 활성레코드는 데이터베이스의 테이블이나 다른 소스에서 자료를 직접 변환한 결과이다.
불행히도, 활성레코드에 비즈니스 규칙 메서드를 추가해 이런 자료구조를 객체로 취급하는 개발자가 흔하다. 이는 바람직하지 않으며 잡종구조가 나오기 때문에 그렇다.
해결책으론, 활성 레코드는 자료구조로 취급하고 비즈니스 규칙을 담으면서 내부자료를 숨기는 객체는 따로 생성하는것이다.
객체는 동작을 공개하고, 자료를 숨긴다. 기존동작을 변경하지 않으면서 새 객체 타입을 추가하기는 쉽지만, 기존 객체에 새 동작을 추가하기는 어렵다. 기존 자료에 새동작을 추가하긴 쉬우나, 기존함수에서 새 자료구조를 추가하기 어렵다.
어떤 시스템을 구현할때, 새로운 자료타입을 추가할때 유연성이 필요하면 객체가 더 적합하다. 하지만 다른 경우 새로운 동작을 추가하는 유연성이 필요하다면 자료구조와 절차적인 코드가 더 적합하고 우수하다.
소프트웨어 개발자는 편견없이 이 사실을 이해해 직면한 문제에 최적인 해결책을 찾아야한다.
무언가 알다가도 모르고, 헷갈린다. 그래서 깔끔히 표로 정리하여 살펴보았다.
추상적 | 구체적(객체) |
---|---|
접근정책을 강제함 | 직교좌표계 사용. |
개별적인 좌표읽기 | 개별적인 좌표읽기 |
설정시 두 값을 한번에 설정해야함 | 좌표 읽고, 설정까지 강제함 |
구현 은닉 | 구현 노출(조회,설정함수 제공) |
절차적인 코드(자료구조) | 객체지향 코드(객체) | |
---|---|---|
함수 | 쉬움 | 어려움(모두 고쳐야함) |
클래스 | 어려움 | 쉬움 |
자료구조 | 어려움(모두 고쳐야함) | 쉬움 |
구현 | 은닉 | 공개(자료 숨김) |
추가 쉬움 | 동작 | 새로운 객체 타입 |
추가 어려움 | 자료 구조 | 동작 |