책 읽기

[Clean Code/클린 코드] - 객체와 자료구조

지팡구 2023. 6. 18. 19:06

Chapter.6 객체와 자료구조

 💡 이번 CHAPTER에서는 객체와 자료구조에 대한 이야기를 하고 있습니다.

 

먼저 변수를 Private(비공개)로 만드는 이유를 “남들이 변수에 의존하지 않게 만들고 싶어서”라고 이야기 하고 있습니다.

여기서 곰곰히 생각해보았습니다. 왜 변수를 Private으로 만드는가?

저는 여기서 떠오르는 키워드가 정보은닉(Data hiding) 밖에 없었습니다.

  1. 접근을 제한하기 위해서 ( Access Modifier )Public 은 외부에서 접근 가능, Private는 외부에서 접근 불가능
    • 코드로 간단히 이해해보겠습니다.
      public class Test{
       
          public static void main(String[] args) {
            
              Car car = new Car();
              
              carObject.setFuel(10);
              System.out.println(carObject.checkFuel());
              
              carObject.setFuel(-10);
              System.out.println(carObject.checkFuel());
          }
      }
       
      class Car
      {
          private int fuel;
          
          void setFuel ( int inputFuel ) {
              if ( inputFuel > 0 && inputFuel <= 100) {
                  this.fuel = inputFuel;
              }
              else {
                  System.out.println("fuel 값이 올바르지 않습니다.");
              }
          }
          
          int checkFuel() {
              return this.fuel;
          }
      }
public class Test{
 
    public static void main(String[] args) {

        Car car = new Car();
        
        carObject.fuel = 10;
        car.checkFuel;
        
        car.fuel = -10;
        car.checkFuel;}
}
class Car

    public int fuel; ( public 을 생략하면 default 정책이 public )
  
    void .checkFuel() {
        System.out.println ("현재 연료양은 " + fuel );
    }
}
  1. 💡 코드를 통해 확인한 바는 다음과 같습니다.내부 구현 함수에서 발생할 수 있는 예외 값에 관한 처리도 가능합니다.
  2. Public 제어자 같은 경우엔 외부에서 값을 직접 대입할 수 있지만, Private 제어자 같은 경우엔 Class 내부에 직접 접근이 불가능하고, 내부의 구현 함수에 의해 접근하고 있습니다.
  3. 여러 종류의 접근자 中 흔히 사용하는 접근자가 public, private (외 2가지 )정도인데, 2가지만 놓고 본다면 둘의 차이점은 아래와 같았습니다.

Q : 그럼 함수라는 계층을 넣는다고 감춰지는 것인가요? ( 인터페이스를 이용해야하나? )

A : 그렇지 않습니다. (인터페이스나 조회/설정 함수만으로 추상화가 이뤄지지 않습니다. )

결국 구현을 감추려면 추상화가 필요합니다.

 

 

💡 추상 인터페이스를 제공해서 사용자가 구현을 모른 채 자료의 핵심 조작을 할 수 있어야 하며, 자료를 세세하게 공개하기 보다는 추상적인 개념으로 표현하는 방식이 좋다고 생각합니다.

 

자료구조와 객체의 차이

  • 객체 : 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개
  • 객체는 동작을 공개하고 자료를 숨깁니다. 그래서 기존 동작을 변경하지 않으면서 새 객체 타입을 추가하기 쉬운 반면, 기존 객체에 새 동작을 추가하기는 어렵습니다.
  • 자료 구조 : 자료를 그대로 공개하며 별다른 함수를 제공하지 않음.
  • 자료구조는 별다른 동작 없이 자료를 노출해서 새 동작을 추가하기 쉽지만, 기존 함수에 새 자료 구조를 추가하기 어렵습니다.

자료와 객체를 이용한 이해력 높이기

  • Sample Code ( 절차 지향 )여기서 절차 지향 코드의 이점과 단점을 한번에 확인할 수 있습니다.
    • 장점 : Geometry 클래스에 새로운 함수를 추가할 때, 도형 클래스는 수정할 필요 x
    • 단점 : 새로운 도형 추가 시 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(Objects 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 클래스에 새로운 함수를 추가할 때, 도형 클래스는 수정할 필요 x
  • 단점 : 새로운 도형 추가 시 Geometry 클래스의 함수를 수정해야 함.

 

 

  • Sample Code ( 객체 지향 )객체 지향의 장점과 단점
    • 장점 : 기존 코드나 함수를 수정하지 않고 새로운 클래스 추가가 쉬움
    • 단점 : 새로운 함수를 추가하기 위해 모든 클래스를 고쳐야 함
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 Rectangle implements Shape {
    private Point center;
    private double radius;
    public final double PI = 3.1415926533589793;

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

객체 지향의 장점과 단점

  • 장점 : 기존 코드나 함수를 수정하지 않고 새로운 클래스 추가가 쉬움
  • 단점 : 새로운 함수를 추가하기 위해 모든 클래스를 고쳐야 함

💡 종합적으로 객체 지향에서 어려운 변경은 절차적인 코드에서 쉬우며, 절차적인 코드에서 어려운 변경은 객체 지향 코드에서 쉽습니다. ( Trade off 발생 & 선택해야함 )

 

< 부록 >

디미터 법칙이란?

  • 객체는 자료를 숨기고, 함수를 공개, 즉 객체는 조회 함수로 내부 구조를 공개하면 안 된다는 의미

기차 충돌 코드란?

  • 여러 객체가 한 줄로 이어진 기차처럼 보인다고 해서 붙여진 네이밍
final String data = ctx.getOps().getScrip().getAbsolute();

이러한 방식은 조잡하고, 만약 위 코드가 객체라면 내부 구조를 숨겨야 하기에 디미터 법칙을 위반, 만약 자료구조라면 이미 노출된 내부 구조를 사용하기에 디미터 법칙 위반아님

이러한 방식 보다는 아래와 같은 방식 권장

Options opt = ctx.getOps();

File scrip = opt.getScrip();

final String data = scrip.getAbsolute();

< 해당 Chapter에 관한 내 생각 >

💡 결국 객체인지, 자료구조인지에 관한 생각이 많이 필요할 것이다. 그 이유는 내가 의도한 바가 객체인지, 자료구조인지 파악이 되어야 정보 은닉을 위한 캡슐화나 여러 인터페이스, 추상화 등등을 이용할 수 있을 것이라 생각이 됩니다.