카테고리 없음

내 코드가 그렇게 이상한가요 ? _ 1,2,3장

ERE 2024. 7. 19. 19:44

1장. 잘못된 구조의 문제 깨닫기

다음의 경우 잘못된 구조의 코드 

  • 의미를 알 수 없는 이름 
    • 컴퓨터 용어 / 일련번호를 매겨 이름을 지으면 코드에서 의도를 읽어내기가 어렵다.
  • 이해하기 어렵게 만드는 조건 분기 중첩
    • if 조건문의 중첩은 이해하기 힘들다. 
  • 수많은 악마를 만들어 내는 데이터 클래스
    • 데이터를 갖고 있기만 하는 클래스를 데이터 클래스라고 부른다.
    • 데이터 클래스에서 선언하는 데이터를 이용한 로직이 필요한데, 이것을 다른 클래스에서 구현하는 일이 벌어지곤 한다. 

데이터와 로직이 분산되어 있는 것을 응집도가 낮은 구조라고 한다. 

이떄, 발생할 수 있는 문제를 보자면. 

  • 코드 중복
  • 수정 누락
  • 가독성 저하 
  • 초기화되지 않은 상태(쓰레기 객체)
  • 잘못된 값 할당

2장. 설계 첫걸음

  • 의도를 알 수 있는 이름 붙이기 
  • 목적별로 변수를 따로 만들어 사용하기 
    • 변수의 재할당은 변수의 용도가 바뀌는 문제를 일으키기 쉽다. 
  • 단순 나열이 아니라, 의미 있는 것을 모아 메서드로 만들기
    • 유지 보수와 변경이 쉬워진다.
  • 관련된 데이터와 로직을 클래스로 모으기 
    • 클래스는 데이터를 인스턴스 변수로 갖고, 인스턴스 변수를 조작하는 메서드를 함께 모아 놓은 것

3장: 클래스 설계 _ 모든 곳과 연결되는 설계 기반

클래스 단위로 잘 동작하도록 설계하기

  • 클래스의 구성 요소 
    • 인스턴스 변수
    • 메서드 -> 인스턴스 변수에 잘못된 값이 할당되지 않게 막고, 정상적으로 조작하는 메서드

왜 이런 구성을 지켜야 하는 걸까 ? 

  • 데이터 클래스의 경우 자기 자신을 보호할 수 있는 로직을 갖고 있지 않음. 초기화 작업을 하는 코드가 다른 클래스에 구현이 되어있기 때문에.
    • 또한, 데이터 클래스는 다른 클래스의 의존도가 높음

모든 클래스터가 갖추어야 하는 자기 방어 임무

  • 생성자로 확실하게 정상적인 값 설정하기 
    • 로우 데이터 객체를 방지하기 위해. 클래스 인스턴스를 생성하는 시점에 확실하게 인스턴스 변수가 정상적인 값을 갖게 만들면 된다. 
class Money {
	int amount;
 	Currency currency;
	
    Money(int amount, Currency currency) {
    	this.amount = amount;
        this.currency = currency;
    }

> 이렇게 하면 인스턴스 변수가 무조건 초기화 된다. 

 

  •  인스턴스 변수를 불변 변수로 만들기
    • 인스턴스 변수에  final 수식자를 붙이면, 한 번만 할당할 수 있다. 
      • 변수 선언 시점 또는 생성자 안에서만 값을 할당할 수 있으며, 이후에는 재할당 할 수 없음
  • 변경하고 싶다면 새로운 인스턴스 만들기
    • 인스턴스 변수의 내용을 변경하는 것이 아니라, 변경된 값을 가진 새로운 인스턴스를 만들어서 사용할 수 있음
class Money {

	Money add(int onther) {
    	int added = amount + other;
        return new Money(added, currency);	
    }
}

> 이렇게 하면 불변을 유지하면서도 값을 변경할 수 있다. 

 

  • 메서드 매개변수와 지역 변수도 불변으로 만들기 
    • 지역 변수와 메서드의 매개변수에  final을 붙여 안정성을 높인다

효과 검토하기 

Class Money {
 final int amount;
 final Currency currency;
 
 Money(final int amount, fianl Currency currency) {
 	if (amount < 0) {
    	throw new IllegalArgumentException("금액은 0이상의 값을 지정해 주세요.");
    }
    if (currency == null) {
    	throw new NullPoninterException("통화 단위를 지정해 주시요.");
	}
    
    this.amout = amount;
    this.currency = currency;
}

Money add(final Money other) {
	if (!currency.equals(other.currency)) {
    	throw new IllegalArgumentException("통화 단위가 다릅니다.");
	}
    
    final int added = amount + ohter.amount;
    return new Money(added, currency);
    }
}

 

클래스 설계란 인스턴스 변수가 잘못된 상태에 빠지지 않게 하기 위해 구조를 만드는 것.

 

프로그램 구조의 문제 해결에 도움을 주는 디자인 패턴

  • 완전 생성자 (complete constructor)
    • 잘못된 상태로부터 클래스를 보호하기 위한 디자인 패턴
      • 쓰레기 객체를 방지하려면, 인스턴스 변수를 모두 초기화 해야만 한다. 
  • 값 객체 (value object)
    • 값을 클래스로 나타내는 디자인 패턴