프로필사진

Go, Vantage point

가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.


Github | https://github.com/overnew/

Blog | https://everenew.tistory.com/





티스토리 뷰

반응형

 

*본 게시물은 [클린 코드] 와 [실용주의 프로그래머] 서적에서 배운 것 들을 잘 활용하기 위해 정리한 글입니다.

*문제시 삭제하겠습니다.

 


 

자료 추상화

 

 조회(get)와 설정(set) 함수를 제공한다면 클래스의 구현은 전혀 감춰지지 않는다. 

인터페이스나 조회, 설정 함수만으로는 추상화가 이뤄지지 않는다.

 

 

자료와 객체의 비대칭

 

자료 구조는 자료를 그대로 공개하며 별다른 함수를 제공하지 않는다.

반면에 객체는 추상화로 자료를 숨기고, 자료를 다루는 함수만 공개한다.

 

물론 객체만이 장점을 가지는 건 아니다. 서로는 상반되는 장점과 단점을 가진다.

 

 

절차 지향 코드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Square{
    public Point topLeft;
    public double side;
}
 
// ... Circle, Rectangle class...
 
public class Geometry{
    public final double PI = 3.14;
    
    //도형의 넓이를 구하는 함수
    public double area(Object shape) {
        if(shape instanceof Square) {
            Square square = (Square)shape;
            return square.side *square.side;
        }else if(shape instanceof Circle) {
            ///Circle, Rectangle class 들마다 넓이 공식 각자 구현
        }
    }
    
}
cs

 

자료 구조를 사용하는 절차 지향 코드는 기존 자료 구조를 변경하지 않아도 새 함수를 추가하기 쉽다.

하지만 새로운 자료구조가 추가된다면 모든 함수를 수정해 주어야 한다.

만약 새로운 Triangle이 추가된다면 area함수는 변경되어야 새로운 자료 구조를 다룰 수 있다.

 

 

다형적인 객체지향 코드

 

1
2
3
4
5
6
7
8
9
10
11
public class Square implements Shape{
    private Point topLeft;
    private double side;
    
    @Override
    public double area() {
        return side*side;
    }
}
 
/// Circle, Rectangle class... 각자 area()함수 구현 필요
cs

 

객체 지향 코드에서는 모든 클래스에 구현을 해주어야 하므로 새로운 함수를 추가하기 힘들다. 

하지만 새로운 클래스를 추가하기는 쉽다. 

Triangle가 추가된다면 해당 클래스만 구현해주면 된다.

 

 

떠라서 모든 것이 객체로 이뤄줘야 한다는 생각은 잘못됐다. 새로운 함수가 여러 번 추가되는 상황에서는 단순한 절차 지향 코드가 적합할 수 있다.

 

 

디미터 법칙

클린 코드 서적에서는 디미터 법칙은 모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다는 휴리스틱 법칙이라고 소개한다.

 

코드를 모듈로 구성하고, 서로의 상호작용을 제한하면 특정 모듈이 변경되더라도 다른 모듈은 문제없이 수행될 수 있다.

예를 들어 한 줄로 이어진 기차처럼 보여서 기차 충돌(train wreck) 이라고 불리는 코드를 봐보자. 

 

1
2
3
4
public void plotData(Date aDate, Selection aSelection) {
    TimeZone tz = aSelection.getRecorder().getLocation().getTimeZone();
    ///...
}
cs

 

기록 객체에서 위치를 가져오고, 다시 시간대를 가져오는 코드이다.

이런 코드는 Selection, Recoder, Location이라는 3가지 클래스가 결합되어 있다.

직접 클래스의 위계구조를 헤집고 다니기보다는 필요한 정보는 직접 물어보도록 바꿔보자.

 

 

1
2
3
4
5
6
public void plotData(Date aDate, TimeZone aTz) {
    
    ///...
}
 
plotData(someData, someSelection.getTimeZone());
cs

 

Selection에 직접 시간대(TimeZone)를 얻을 수 메서드를 추가하자.

Selection도 Recoder에게 시간대를 얻을 것이고, Recoder는 Location에게 시간대를 얻을 것이다.

서로가 자신의 책임을 다하면 의존 관계를 대폭 줄일 수 있다.

이제 plotData() 함수는 시간대가 어디서 왔는지 상관하지 않는다. 즉, 속사정은 몰라도 되는 것이다.

 

실용주의 프로그래머 서적에서는 디미터 함수 법칙을 다음과 같이 설명한다.

한 객체가 제공하는 메서드에 접근하기 위해 또 다른 객체를 통하는 것을 허용하지 않는 것.

 

물론 디미터 법칙을 지키기 위해서는 요청 전달 간단히 위임하는 메서드를 상당수 만들어야 하기 때문에 성능 면에서는 비효율적이다. 따라서 법칙과 반대로 결합도를 높이는 대신 성능 향상을 노리는 방법도 있을 것이다.

 

 

 

추가 참조 서적: 실용주의 프로그래머 (앤드류 헌트, 데이비드 토머스 저) 디미터 법칙 227p

반응형
댓글
반응형
인기글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함