비즈니스 요구사항
영화관에 입장하는 관객의 초대권을 확인하고, 만약 초대권이 없다면 티켓 구매 후 입장을 시키고, 초대권이 있다면 티켓으로 바꿔준 후 입장 시킨다.
객체 지도 설계
객체와 자료 구조
- 객체 : private 형식의 변수와 함수가 존재하는 클래스
- 자료 구조 : public 형식의 변수만 가지고 있고, 함수가 없는 클래스
변수를 private 접근 제한자로 선언하는 이유는 남들이 변수에 의존하지 않게 만들고 싶어서이다. 그런데 웃긴점은 우리는 자연스럽게 getter/setter 함수를 public 하게 선언하여 외부에 노출한다. 과연 이것이 맞는것일까?
OOP 스러운 클래스는 추상 인터페이스를 제공해 클래스의 사용자가 구현을 모른 채 자료의 핵심을 조작할 수 있어야하는 것이 진정한 의미의 클래스이다.
자료(Data Type: Has Only Variables) / 객체(Instances: Members + Method)의 비대칭
- 객체(Object)는 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개한다.
- 자료 구조(Structure)는 자료를 그대로 공개하며 별다른 함수는 제공하지 않는다. 자료 구조를 다루는 함수는 외부에 존재한다.
절차지향 기반의 코드에서
세 도형을 정의한 클래스(Square, Rectangle, Circle)이 있다. 도형 클래스는 자료 구조이다. 이 도형을 다루는 책임은 Geometry라는 클래스가 가진다. 그래서 도형들의 둘레를 구하는 함수를 추가하고 싶다면 Geometry 클래스에 함수만 추가하면 되는 것이다. 이때 도형 클래스. 즉, 자료구조는 아무런 영향을 받지 않는다.
public class Square {
public Point topLeft;
public double side;
}
public class Rectangle {
public Point topLeft;
public double height;
public double width;
}
public class Circle {
public Point center;
public double radius;
}
public class Geometry {
public final double PI = 3.141592653589793;
public double area(Obeject shape) throw NoSuchShapeException
{
if(shape instanceof Square) {
Square s = (Square)shape;
return s.side * s.side;
}
else if(shape instanceof Rectangle) {
Rectangle r = (Rectangle)shape;
return r.height * r.width;
}
else if(shape instanceof Circle) {
Circle c = (Circle)shape;
return c.radius * c.radius;
}
throw NoSuchShapeException()'
}
}
하지만 문제점은 만약 새 도형을 추가하고 싶다면, Geometry에 속한 함수의 내용을 모두 고쳐야 한다는 것이다. 즉, else if 분기문을 각 함수마다 추가해줘야 한다.
따라서 자료 구조 형태의 코드는 기능 추가는 쉽지만, 종류의 추가는 변경의 전파가 발생할 수 있다는 단점을 가진다.
반면 객체지향 코드에서
area()는 Shape Interface에서 상속하는 개념으로 다형 메서드이다. 그러므로 새 도형을 추가해도(종류의 추가) 기존 함수에 아무런 영향을 미치지 않는다. 반면 새로운 기능을 추가하고 싶다면, 변경의 전파가 발생한다.
- 디미터 법칙: 모듈은 자신이 조작하는 객체의 내부구현을 몰라야 한다.
- 객체는 상태를 숨기고 함수를 공개한다. 상태를 숨겨야 하기 때문에 조회 함수로 내부 구조를 공개하면 안된다라는 의미이다.
public class Square implements Shape {
private Point topLeft;
private double side;
public double area(){
return side * side;
};
}
public class Rectangle implements Shape {
private Point topLeft;
private double width;
private double height;
public double area(){
return width * height;
};
}
따라서
객체와 자료 구조는 근본적으로 양분된다. 객체지향 코드에서 어려운 변경은 절차적인 코드에서 쉬우며, 절차적인 코드에서 어려운 변경은 객체 지향 코드에서 쉽다. 결론은 항상 객체지향이 옳은 것이 아니고, 그때 그때 적합한 방식을 적용해서 개발하는 것이 올바르다는 것이다.
부록
- 자료 구조체의 전형적인 형태는 공개 변수만 있고, 함수가 없는 클래스이다. 이런 자료 구조체를 때로는 자료 전달 객체(DTO)라고 한다.
'책 - 요약 정리 > 클린 코드' 카테고리의 다른 글
클린 코드 (0) | 2023.09.05 |
---|---|
3장. 함수 (0) | 2023.09.01 |
2장. 의미 있는 이름 (0) | 2023.08.31 |