클린코드 6장

6장 객체와 자료 구조

자료 추상화

아무 생각 없이 get(), set() 함수를 난사한다고 변수와 구현을 숨길 수 있는 게 아니다. 변수 사이에 함수라는 계층을 넣는다고 구현이 저절로 감춰지지는 않는다. 구현을 감추려면 추상화가 필요하다. 자료를 세세하게 공개하기 보다는 추상적인 개념으로 표현하는 것이 좋다.

자료/객체 비대칭

객체와 자료구조는 근본적으로 양분된다..
면접 대비를 하면서 절차 지향 프로그래밍 vs 객체 지향 프로그래밍 이라는 질문을 본 적이 있다. 이 장에서 말하고자 하는게 그것이다.

(자료구조를 사용하는) 절차적인 코드는 기존 자료 구조를 변경하지 않으면서 새 함수를 추가하기 쉽다. 반면, 객체 지향 코드는 기존 함수를 변경하지 않으면서 새 클래스를 추가하기 쉽다.

이 말은 곧

절차적인 코드는 새로운 자료 구조를 추가하기 어렵다. 그러려면 모든 함수를 고쳐야 한다. 객체 지향 코드는 새로운 함수를 추가하기 어렵다. 그러려면 모든 클래스를 고쳐야 한다.

이 말과 같다.

public class Square implements Shape{'
	private double side;
    
    pulibc double area(){
    	return side*side
    }
...
}

뭐 대충 이런함수가 있다치면....Shape에 함수 하나를 추가하면 Square는 빨리 이 함수를 구현하라며 에러 메세지를 띄울 것이다. Square 말고 Circle, Rectangle 이런애들도 잔뜩 만들어놨다면? 일일이 함수를 새로 구현해야겠지... 객체 지향 코드가 새로운 함수를 추가하기 어렵다는 게 이런 뜻인 것 같다.

public class Square {'
	public double side;    
...
}

public class Geometry{
	public double area(Object shape){
    	if (shape instanceof Square){
        	Square s = (Square)shape;
            return s.side*s.side
        }
    }
}

반면 이렇게 Square를 implement 없이 그냥 단순히 자료구조 하나 만든다는 느낌으로 달랑 구현했다면? 넓이 구하기는 area(Object shape) 이렇게 Square 밖에 만들었다면? 새 함수를 추가한다고 해서 Square는 영향을 받지 않는다. 다만 새 클래스 Circle을 만들고 싶다면, 붕어빵 틀에 넣고 찍어대는 것 같은 OOP보단 노력을 좀 더 들여야겠지...

디미터 법칙

디미터 법칙이란?
모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다는 법칙

디미터 법칙하에, 클래스 C의 메서드 f가 호출해도 되는 메서드는 아래와 같다.

  • 클래스 C의 메서드
  • f가 생성한 객체의 메서드
  • f 인수로 넘오는 객체의 메서드
  • C 인스턴스 변수에 저장된 객체

🔎 기차 충돌
여러 객체가 한줄로 줄줄이 이어져서 호출호출호출...하는 상황. 예를 들어

final String outputDir=dtxt.getOptions().getScratchDir().getAbsolutePath()

이런 상황을 기차 충돌이라고 부른다. 조잡하니까 피하자...

Option opts = ctxt.getOptions();
File scratchDir=opts.getScratchDir();
final String outputDir=scratchDir.getAbsolutePath()

이렇게 나누는 것이 바람직하다.
디미터 법칙에 위배된다는 논란(?)을 피하려면

final String outputDir=ctxt,options.scratchDir.getAbsolutePath()

이렇게 해도 좋다.

🔎 구조체 감추기

final String outputDir=ctxt,options.scratchDir.getAbsolutePath()

이렇게 바꾸어도 줄줄이 사탕처럼 엮여있는 건 똑같다. 객체라면 내부 구조를 감춰야하는데 막 드러나고 있다. 차라리 객체한테 알아서하라고 시키면 어떨까?

BufferedOutputStream bos=ctxt.createScratchFileStream(classFileName)

상당히 괜찮아 보인다.

🔎 잡종 구조
때때로 절반은 객체지향, 절반은 절차지향인 잡종 구조가 나올 수 있다. 예를 들면 객체지향에서 절차지향의 장점을 살리고 싶어서 막 섞을 수 있겠지.. 하지만 이렇게 하면 두 방식의 단점만 모아놓게 될 확률이 높다고 한다.

자료 전달 객체

자료 구조체의 전형적인 형태는 공개 변수만 있고 함수가 없는 클래스다. 이런 자료구조체를 때로는 자료 전달 객체(Data Transfer Object)라고 한다. 일반적으로 DTO는 데이터베이스에 저장된 가공되지 않은 정보를 애플리케이션 코드에서 사용할 객체로 변환하는 일련의 단계에서 가장 처음으로 사용하는 구조체다.

좋은 웹페이지 즐겨찾기