객체와 자료 구조
자료 추상화
public class Point {
public double x;
public double y;
}
public interface Point {
double getX();
double getY();
void setCartesian(double x, double y);
double getR();
double getTheta();
void setPolar(double r, double theta);
}
- 클래스와 인터페이스 모두 2차원 점을 표현
- 아래의 인터페이스는 자료 구조 이상을 표현
- 클래스 메서드가 접근 정책을 강제
- 변수에 getter와 setter를 넣는다고 구현이 저정로 감춰지지 않음
- 구현을 감추려면 추상화가 필요
public interface Vehicle {
double getFuelTankCapacityInGallons();
double getGallonsOfFasoline();
}
public interface Vehicle {
double getPercentFuelRemaining();
}
- 첫 번재 인터페이스는 구체적인 숫자를 알려주는 메서드로 구성
- 두 번째 인터페이스는 추장적인 개념으로 알려줌
- 퍼센트로 알려줌으로써 실제 값이 어떻게 구성되어있느지는 숨김
자료/객체 비대칭
- 앞의 두가지 예는 객체와 자료구조 사이에 벌어진 차이를 보여줌
- 객체는 추상화 뒤로 자료를 숨긴 채 자료를 다루는 함수만 공개
- 자료구조는 자료를 그대로 공개하며 함수를 제공하지 않음
public class Square {...}
public class Rectangle {...}
public class Circle {...}
public class Geometry {...}
- 위와 같은 코드는 Geometry안에서 Squre, Rectangle, Circle 클래스를 다룰때 새로운 클래스를 추가하면 Geometry 클래스를 수정해야함
public class Sqaure implements Shape {...}
public class Rectangle implements Shape {...}
public class Circle implements Shape {...}
- 반면 위와 같은 코드는 새로운 클래스가 추가되어도 Geometry가 수정될 필요가 없음
- 반면 새 함수를 추가하고 싶으면 도형 전부를 고쳐야함
- 새로운 자료 타입이 필요한 경우 아래와 같은 객체 지향법이 적합
- 새로운 함수가 필요한 경우 위와 같은 절차적 코드가 적합
디미터 법칙
- 디미터 법칙은 잘 알려진 휴리스틱으로 모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다는 법칙
- 좀더 정확하게 표현하면 클래스C의 메서드 f는 다음과 같은 객체의 메서드만 호출해야함
- 클래스 C
- f가 생성한 객체
- f인수로 넘어온 객체
- C 인스턴스 변수에 저장된 객체
- 즉 다음과 같은 코드는 디미터 법칙을 어기는것임(기차 충돌)
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
// 개선
Options outs = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();
- 첫 번째 코드는 함수 하나가 아는 지식이 너무많음, 또한 계속해서 반환된 객체를 사용하는 기차충돌 형태
- 위 예가 디미터 법칙을 위반하는지 여부는 ctxt, scratchDir, outputDir이 객체인지 아니면 자료구조인지에 달려있음
- 객체라면 내부 구조를 숨겨야하므로 확실히 디미터 법칙을 위반
- 자료구조라면 내부 구조를 노출해야하므로 디미터 법칙이 적용되지 않음
- 잡종구조
- 구조체 감추기
자료 전달 객체
- 자료 구조체의 전형적인 형태는 공개 변수만 존재하고 함수는 없는 클래스
- Data transfer Object(DTO) 라고 함