이 글은 개발자 필독서인 클린 코드를 읽으며 습득한 내용을 정리한 글입니다. 모든 출처는 해당 저서에 있습니다.
💡 변수를 private으로 정의하는 이유
변수에 대한 의존성을 줄이고 변수 타입이나 구현의 변경을 쉽게하기 위해서
자료는 추상적인 개념으로 표현하는 편이 낫다. 단, 인터페이스나 조회/설정 함수만으로 추상화할 수 없다.
public class Point {
public double x;
public double y;
}
public interface Vehicle {
double getFuelTankCapacityInGallons();
double getGallonsOfGasoline();
}
public interface Point {
double getX();
double getY();
void setCartesian(double x, double y);
double getR();
double getTheta();
void setPolar(double r, double theta);
}
public interface Vehicle {
double getPercentFuelRemaining();
}
절차적 코드 | 객체 지향 코드 | |
---|---|---|
데이터 구성 | 자료 구조 | 객체 |
장점 | 기존 자료 구조를 변경하지 않고 새로운 함수를 추가하기 쉬움 | 기존 함수를 변경하지 않고 새로운 클래스를 추가하기 쉬움 |
단점 | 새로운 자료 구조를 추가하려면 기존의 모든 함수를 수정해야 함 | 새로운 함수를 추가하려면 기존의 모든 클래스를 수정해야 함 |
적합한 경우 | 새로운 함수(기능)가 자주 추가되어야 하는 경우 | 새로운 자료 타입(데이터 구조)이 자주 추가되어야 하는 경우 |
모듈은 자신이 조작하는 객체의 속사정을 몰라야 한다.
객체는 자료를 숨기고 함수를 공개한다. 즉, 조회 함수로 내부 구조를 공개하면 안 된다.
메소드 호출이 허용되는 객체
종류 |
---|
클래스 C |
f가 생성한 객체 |
f 인수로 넘어온 객체 |
C 인스턴스 변수에 저장된 객체 |
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
Options opts = ctxt.getOptions();
File scratchDir = opts.getScratchDir();
final String outputDir = scratchDir.getAbsolutePath();
위 코드를 사용하는 함수는 많은 객체를 탐색할 수 있으나, 디미터 법칙을 위반하는지 여부는 ctxt, Options, ScratchDir이 객체인지, 자료 구조인지에 따라 달라진다.
자료 구조 | 객체 | |
---|---|---|
위반 여부 | O | X |
이유 | 내부 구조를 숨겨야 하므로 | 내부 구조를 노출하므로 |
다만, 조회 함수 사용으로 인한 혼란을 초래하는 것을 막기 위해 다음과 같은 소스 코드로 수정할 것을 권한다.
final String outputDir = ctxt.options.scratchDir.absolutePath;
내부 구조를 드러내지 않고, 모듈에서 함수가 자신이 몰라야 하는 여러 객체를 탐색할 필요가 없도록 소스 코드를 작성하도록 한다.
ctxt.getAbsolutePathOfScratchDirectoryOption();
ctx.getScratchDirectoryOption().getAbsolutePath();
String outFile = outputDir + "/" + className.replace('.', '/') + ".class";
FileOutputStream fout = new FileOutputStream(outFile);
BufferedOutputStream bos = new BufferedOutputStream(fout);
BufferedOutputStream bos = ctxt.createScratchFileStream(classFileName);
public class Address {
private String street;
private String city;
private String state;
private String zip;
public Address(String street, String city, String state, String zip) {
this.street = street;
this.city = city;
this.state = state;
this.zip = zip;
}
public String getStreet() {
return street;
}
public String getCity() {
return city;
}
public String getState() {
return state;
}
public String getZip() {
return zip;
}
}
📖 참고
- 로버트 C. 마틴, 『Clean Code 클린 코드 애자일 소프트웨어 장인 정신』, 박재호·이해영 옮김, 케이앤피북스(2010), p147-158.