ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ♻️[클린코드] #5 객체와 자료구조
    Study/클린코드 2022. 6. 30. 17:10

     

    객체와 자료구조로 데이터 표현하기

    ♻️ 자료구조(data structure) vs 객체(object)

     - 공통점 

    둘 다 클래스를 통해 만들어진다.

     

     - 차이점 

    자료구조(Data Structure) 객체(Object)
    데이터 그 자체 비즈니스 로직과 관련
    자료를 공개해야한다.(이 클래스가 어떤 프로퍼티를 가지고 있는지 공개) 자료를 숨기고, 추상화
    (자료를 다루는 함수만 공개)
    변수 사이에 조회 함수(getter)와 설정 함수(setter)로 변수를 다룬다고 객체가 되지 않는다. 추상 인터페이스를 제공해 사용자가 구현을 모른 채 자료의 핵심을 조작할 수 있다.

     

     - 상황에 맞는 선택 

    자료구조 사용 : (절차적인 코드) 기본 자료 구조를 변경하지 않으면서 새 함수를 추가하기 쉬움

    새로운 자료구조를 추가하기 어려움(그러려면 모든 함수를 고쳐야함)

     

    객체지향 코드 : 기존 함수 변경하지 않으면서 새 클래스 추가하기 쉬움

    새로운 함수를 추가하기 어려움(그러려면 모든 클래스를 고쳐야함)

     

    Q. 휴대폰 배터리처럼 실제 수치는 중요하지 않고, 퍼센트만 중요하다면?

    A. 객체를 사용하는 것이 좋다. 사용자 관점에 맞춰서 비즈니스 로직을 사용하는 것이 용이

     


    ♻️ 객체 - 디미터 법칙

     - 휴리스틱 

    경험에 기반하여 문제를 해결하기 위해 발견한 방법. 의사결정을 단순화하기 위한 법칙들

    경험적으로 만들어낸 법칙 (정답이 있는 과학적인 법칙 X)

     

    클린코드도 휴리스틱이라고 볼 수 있다.

     

     - 디미터의 법칙 

    클래스 A의 메서드 f는 아래와 같은 객체의 메서드만 호출해야 한다.

    1) 클래스 A 자기 자신
    2) 자신이 생성한 객체
    3) 자신의 인수로 넘어온 객체
    4) A 인스턴스 변수에 저장된 객체 

     

     - 기차 충돌 

    디미터의 법칙에 어긋나는 상황

    나, 내가 가지고 있는 변수, 인스턴스에만 접근해야 하는데 그렇지 않을 때 연쇄작용이 일어날 때 발생

    // 객체 - 기차 충돌. 디미터의 법칙 위배
    final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
    
    // 자료구조 - OK
    final String outputDir = ctxt.options.scratchDir.absolutePath;
    
    // 객체에 대한 해결책 X, getter를 통했을 뿐, 값을 가져오는 것은 자료구조이다.
    ctxt.getOptions().getAbsolutePathOfScratcDir()
    
    // 근본적인 해결책(근본 원인을 생각하기)
    // 객체는 자료를 숨기곡 자료를 다루는 함수만 공개한다.
    BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);

    ♻️ DTO

     - Data Transfer Object 

    다른 계층 간 데이터를 교환할 때 사용하는 자료구조

    로직 없이 필드만 가짐

    일반적으로 클래스명 Dto(또는 DTO)로 끝남

    getter/setter를 갖기도 한다. (아니면 멤버 변수 속성을 public으로 해서 getter와 setter없이 사용)

     

    public class AddressDto {
    	private String street;
    	private String zip;
    }
    
    public AddressDto(String street, String zip) {
    	this.street = street;
    	this.zip = zip;
    }
    
    public String getStreet() {
    	return street;
    }
    
    public String getZip() {
    	return zip;
    }
    
    public String setZip(String zip) {
    	this.zip = zip;
    }

     

     - Beans 

    * Java Beans : 데이터 표현이 목적인 자바 객체

    멤버 변수는 private 속성이다.

    getter와 setter를 갖는다.


    ♻️ Active Record

     - Active Record 

    Database row를 객체에 맵핑하는 패턴 (자료구조)

    비즈니스 로직 메서드를 추가해 객체로 취급하는 건 바람직하지 않아서 객체는 따로 생성한다.

    (하지만 객체가 많아지면 복잡하고 가까운 곳에 관련 로직이 있는 것이 좋으므로 현업에서는 Entity에 간단한 메서드를 추가해 사용한다.)

     

    Active Record Data Mapper (주로 사용하는 패턴)
    객체가 row를 담을 뿐 아니라 DB에 대한 접근을 포함한다. row를 담는 객체와 DB에 접근할 수 있는 객체가 분리되어 있다.
    속성을 담을 뿐 아니라, 생성 수정도 객체 안에서 수행할 수 있다. 값을 담는 객체와 생성, 수정 등 액션을 담당하는 객체가 따로 있다.
    ex) Ruby on rails ex) Hibernate

     


     

    클래스 설계할 때 상황에 따라 객체나 자료구조로 구분해서 설계하고 만약 객체라면 디미터 법칙을 지키자!