24 May 2017
Implementation Patterns 02
State
- 객체는 외부에 드러나는 행위 와 행위를 지원하기 위한 상태 를 묶어주는 편리한 단위
- 객체 사용으로 프로그램에 있는 모든 상태를 잘게 쪼개서 적당한 곳에 저장할 수 있다.
- 객체를 통해 변경할 수 있는 상태의 범위가 훨씬 줄어들므로, 코드 수정시 어떤 영향을 받을지 분석하기 쉽다.
- 상태 관련 패턴
- 상태: 시간에 따라 변화하는 값을 사용하여 연산
- 접근: 상태에 대한 접근을 제한해서 유연성을 조절
- 직접 접근: 객체 내의 상태를 직접 접근
- 간접 접근: 좀 더 나은 유연성을 위해 메소드를 통해 상태 접근
- 공용 상태: 클래스의 모든 인스턴스에 적용되는 상태는 필드에 저장
- 가변 상태: 같은 클래스의 인스턴스마다 다른 상태를 유지해야할 경우, 상태를 맵에 저장
- 외재 상태: 객체와 연동되는 특수 상태는 상태의 소유자가 소유하는 맵에 저장
- 변수: 상태 접근에 필요한 네임스페이스 제공
- 지역 변수: 지역 변수는 단일 범위내에서만 유효한 상태를 저장
- 필드: 필드는 객체 생성될 때부터 소멸될 때까지 상태를 저장
- 파라미터: 파라미터는 메소드가 활성화된 동안 상태를 전달
- 수집 파라미터: 여러 개의 메소드를 통해 복잡한 결과를 얻기 위해 파라미터 전달
- 파라미터 객체: 자주 사용하는 긴 파라미터 목록은 객체로 만들어서 통합
- 상수: 변하지 않는 상태는 상수로 저장
- 역할 제시형 작명: 변수 이름은 연산에서의 역할을 반영하여 짓는다.
- 선언형 타입: 변수에 대한 일반적 타입을 선언한다.
- 초기화: 변수 초기화는 가급적 선언적으로 한다.
- 열성적 초기화: 인스턴스가 생성될 때 필드를 초기화한다.
- 게으른 초기화: 초기화 비용이 높은 객체의 경우, 객체가 실제 사용되기 직전에 초기화한다.
상태
- 상태는 프로그래밍에 있어서 유용한 도구
- 변수나 할당을 사용하지 않는 프로그래밍에서는 수많은 효과적인 사고 기법들을 포기해야 함
- 객체지향언어는 상태를 다루는데 적합한 전략
- 전체 시스템을 매우 작은 단위로 쪼갠 후, 각각에 대해 엄격한 접근을 적용하여 알지 못하는 사이에 상태가 변해버리는 문제를 줄여준다.
- 객체를 사용하면 빠르고 정확하게 변수에 대한 모든 접근을 확인할 수 있다.
- 서로 유사한 상태를 묶어서 효과적으로 관리
- 두 개의 상태가 동일한 연산에서 사용될 경우
- 동일한 시점에 생성되고 소멸될 경우
직접 접근
- 데이터를 가져오거나 저장하는 것을 나타내는 가장 간단한 방법은 다음과 같이 직접 변수 접근을 사용하는 것이다.
- 위와 같이 직접 변수에 접근하는 것은 표현이 명확해진다. 그러나 이 명확성을 위해 유연성이 희생된다. 프로그램 여러 부분에서 어떤 변수에 직접 접근하면 수정 시, 모든 부분을 하나하나 바꾸어야 한다.
직접 접근이 많은 코드는 원활한 커뮤니케이션을 방해하는 요소이다.
간접 접근
- 메소드 호출을 통해 외부에 상태 변화를 숨김으로써 데이터에 접근하는 코드가 유연성을 확보할 수 있다.
- 간접 접근이 유용한 경우로 2개 이상의 데이터가 서로 의존관계가 있을 경우이다.
Rectangle void setWidth(int width) {
this.width = width;
area = width * height;
}
공용 상태
- 프로그램 작성시, 여러 연산에서 같은 데이터 요소를 사용하는 경우가 있다.
- 이런 경우는 다음과 같이 클래스로 각 데이터 요소들을 묶어 사용하는 것이 좋다.
class Point {
int x;
int y;
}
- 위와 같이 공용 상태를 사용하면 코드만 봐도 이 객체를 만들기 위해 어떤 작업이 필요한지 쉽게 알 수 있다. 또한 이에 대한 정보를 명확하고 정확하게 전달할 수 있다.
변수
- 변수를 범위에 따라 분류
- 지역 변수
- 필드 변수
- public / default / protected / private
- 정적 변수
- 대부분의 경우에 지역 변수를 사용하고, 필요할 때 정적 변수와 필드 변수를 사용해서 객체 간의 의존성을 줄여야 한다.
- 어떤 메소드가 수행 될 때만 필드 변수를 유효화할 수도 있지만, 이런 코드는 좋지 않다.
- 변수의 생명은 가급적 변수의 범위에 가까워야 한다.
- 같은 범위에서 정의된 변수는 모두 같은 생명 기간을 가져야 한다.
지역 변수
- 지역 변수는 변수가 선언된 지점이 속한 범위에서만 접근할 수 있다.
- 가급적 지역 변수는 사용되기 직전 에 선언하는 것이 좋다.
필드 변수
파라미터
상수
- 변화하지 않는 데이터를 프로그램의 여러 부분에서 사용하는 경우 static final 로 선언
- 상수 이름을 통해 그 값의 뜻을 명확하게 전달할 수 있다.
열성적 초기화
- 변수가 선언되거나 생성되자마자 초기화
- 가능하다면 선언문에서 초기화하는 것이 좋다.
- 선언문에 필드를 초기화할 수 없다면 생성자에서 초기화
class Library {
List<Person> members = new ArrayList<>();
...
}