[클린코드] 6장 객체와 자료구조

JUN·2024년 8월 16일
0

클린코드

목록 보기
6/14

서론.

해당 10p 짜리 6장의 내용은 나의 OOP에 대한 이해가 얼마나 부족한지를 상기시켰다.

짧은 식견으로 자료를 추상화하고 객체를 나누는 것에 대해 익숙치 않고 추상화하는 이유가 경험적으로 와닿지 않으니 이해하기가 힘들었다.

그래도 요약해보려고 한다.

자료 추상화.

구현을 외부로 노출하고 구현을 완전히 숨긴다.

추상화의 중요성

  1. 복잡성 감소: 객체의 내부 구현을 숨기면, 사용자는 객체를 더 쉽게 사용할 수 있다.
  2. 유지보수 용이: 내부 구현이 변경되더라도 외부 인터페이스는 변하지 않기 때문에 코드 수정이 적어진다.
  3. 캡슐화: 객체의 상태를 외부에서 직접 변경할 수 없게 하여, 데이터 무결성을 유지한다.
  4. 독립성 증가: 객체 간의 상호 의존성이 줄어들어, 각각의 객체를 독립적으로 관리할 수 있다.

객체와 자료 구조

  • 객체: 내부 데이터를 숨기고, 데이터를 조작하는 메서드만 외부에 제공한다.
  • 자료 구조: 데이터를 그대로 외부에 공개하며, 별다른 메서드를 제공하지 않는다.

이 두 개념은 서로 정반대라고 할 수 있다. 객체는 데이터를 은닉하고 동작(메서드)을 공개하며, 자료 구조는 데이터를 공개하고 동작을 포함하지 않는다.

예제 1: 절차적 도형 (자료 구조)

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(Object shape) throws 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 PI * c.radius * c.radius;
        }
        throw new NoSuchShapeException();
    }
}

여기서 도형 클래스는 단순한 자료 구조로, 데이터를 그대로 공개한다. Geometry 클래스가 이 자료 구조들을 사용하여 도형의 면적을 계산한다.

예제 2: 객체 지향 도형 (객체)

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 height;
    private double width;

    public double area() {
        return height * width;
    }
}

public class Circle implements Shape {
    private Point center;
    private double radius;
    public final double PI = 3.141592653589793;

    public double area() {
        return PI * radius * radius;
    }
}

여기서 각 도형 클래스는 Shape 인터페이스를 구현하고, 자신만의 area 메서드를 가진다. Geometry 클래스는 필요 없다. 새로운 도형을 추가해도 기존 클래스에는 아무런 영향을 주지 않는다.

요약

  1. 절차적 코드:
    • 장점: 새로운 함수를 쉽게 추가할 수 있다.
    • 단점: 새로운 자료 구조를 추가하기 어렵다. 모든 함수에서 자료 구조에 대한 처리를 수정해야 한다.
  2. 객체 지향 코드:
    • 장점: 새로운 자료 구조(클래스)를 쉽게 추가할 수 있다.
    • 단점: 새로운 함수를 추가하기 어렵다. 모든 클래스에 새로운 메서드를 추가해야 한다.

적용

객체 지향과 절차적 코드의 차이를 이해하면, 어떤 상황에서 어떤 방식을 사용하는 것이 적합한지 판단할 수 있다.

  • 새로운 자료 구조(타입)를 추가해야 하는 경우: 객체 지향 접근 방식이 더 적합한다.
  • 새로운 기능(함수)을 추가해야 하는 경우: 절차적 접근 방식이 더 적합한다.

디미터 법칙

디미터 법칙은 "모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다"는 법칙이다. 즉, 객체는 내부 구조를 숨기고, 필요한 동작만을 외부에 공개해야 한다는 뜻이다.

디미터 법칙을 지키면 코드의 결합도가 낮아지고, 유지보수가 쉬워진다.

잡종 구조

  • 잡종 구조는 객체와 자료 구조의 특징을 절반씩 섞은 것이다.
  • 이런 구조는 새로운 함수와 새로운 자료 구조를 추가하는 데 모두 어려움을 겪는다.

따라서, 잡종 구조는 피하는 것이 좋다. 객체는 동작을 공개하고 자료를 숨겨야 하며, 자료 구조는 자료를 공개하고 동작을 숨겨야 한다.

결론

객체 지향 프로그래밍과 절차적 프로그래밍의 차이를 이해하고, 상황에 맞게 적절히 적용하는 것이 중요한다. 객체는 동작을 공개하고 자료를 숨기고, 자료 구조는 자료를 공개하며 동작을 숨긴다. 이 두 가지 접근 방식을 잘 활용하면, 더 유연하고 유지보수하기 쉬운 소프트웨어를 작성할 수 있다.

본 글은 클린코드 스터디에서 읽은 내용과 질문을 재구성한 글 입니다.

profile
순간은 기록하고 반복은 단순화하자 🚀

0개의 댓글