시간적 결합을 해결한 시간 바꾸기
받아올림도 하는 시간 바꾸기의 시간적 결합 관계 는 한눈에 보이지 않아서 실수하기 쉬움
- 실제 시계에 그 해결책이 있음

시계 태엽(분침)을 돌리면 분침도 이동하고 시침도 동시에 이동함
통합해서 가장 작은 단위인 초 단위로 적용하면 됨

setter을 모두 제거하고 addSeconds()를 추가
public void addSeconds(short seconds) {
final int HALF_DAY_IN_SECONDS = 60 * 60 * 12;
int value = this.seconds + seconds;
while (value < 0) {
value += HALF_DAY_IN_SECONDS;
}
this.seconds = (byte) (value % 60);
value = value / 60;
value += this.minutes;
this.minutes = (byte) (value % 60);
value = value / 60;
value += this.hours - 1;
this.hours = (byte) (value % 12 + 1);
}아날로그 시계라서 12시까지 고려
- 음수일 때
60 * 60 * 12를 더함
시, 분, 초는 모두 byte 자료형으로 충분함
- 시의 범위
[0, 11] - 분, 초의 범위
[0, 59]
매개변수 seconds 자료형은 short
- 넉넉하게 크게 설정
this.seconds + seconds 에서 매개변수 seconds가 short의 최대값이 들어오는 오버플로우 발생을 막기 위해 좌변의 value의 자료형은 int
음수에 대한 처리는 처음에 1번하면 이후 초, 분, 시를 구하는 나머지 연산에서 value값은 양수일 수 밖에 없음
-1시간을 더하는 개념이나11시간을 더하는 개념이나 동일하
addSeconds() 메소드의 복잡함

setter의 매개변수는 한 개인데 실제로 3개의 멤버 변수를 변경
- 상태를 저장하는 멤버 변수가 너무 많음

이럴 때 상태를 저장하는 변수를 하나로 관리
- 시/분/초를 알고 싶을 때마다 계산해 보여주기

넉넉하게 byte에서 int로 확장
초기화할 때 0시, 0분, 0초로 초기화
- before 구현에는 시간을 12로 초기화
- 시계는 12부터 시작해서 1,2 … 11까지 표현하니까
after 구현은 보여주기용 데이터와 저장하는 데이터를 분리함
- 저장할 때 초로 통합해서 저장함
- 초로 통합했기에 0시, 0분, 0초로 시작
- 시계를 구매하고 미개봉 상태
- 데이터 추상화 개념
- 클래스 외부에서는 어떻게 저장하는 지 모름
- 클래스 외부에서는 오직 시, 분 , 초로 표현하는 것에 관심
- 초로 통합했기에 0시, 0분, 0초로 시작
before 구현은 보여주기 용도의 데이터와 상태 저장용 데이터를 구분하지 않았음
public class Clock {
private int seconds;
public byte getHours() {
int hours = this.seconds / 60 / 60;
return hours == 0 ? 12 : (byte) hours;
}
public byte getMinutes() {
return (byte) (this.seconds / 60 % 60);
}
public byte getSeconds() {
return (byte) (this.seconds % 60);
}
public void addSeconds(short seconds) {
final int HALF_DAY_IN_SECONDS = 60 * 60 * 12;
int value = this.seconds + seconds;
while (value < 0) {
value += HALF_DAY_IN_SECONDS;
}
this.seconds = value % HALF_DAY_IN_SECONDS;
}
}getter에서 this.seconds가 음수인지 확인할 필요 없음
- 외부에서 호출하는
addSeconds함수에 매개변수seconds는 음수가 들어올 수 있음- 하지만
this.seconds값을 설정할 때 처리해서 반드시 양수가 되도록 설정함- 내부의 데이터(
this.seconds)는 양수로 유지- 내부의 상태를 유효하게 유지하는 캡슐화 개념
- 내부의 데이터(
- 하지만