티스토리 뷰
아래 링크의 정리 및 요약입니다.
https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html
Constructors Must Be Code-Free
It is a bad idea to put executing statements into class constructors because that leads to side effects and uncontrollable behavior.
www.yegor256.com
생성자는 반드시 코드가 없어야 한다.
public final class EnglishName implements Name {
private final String name;
public EnglishName(final CharSequence text) {
this.name = text.toString().split(" ", 2)[0];
}
@Override
public String first() {
return this.name;
}
}
위 코드는 문제는 무엇일까? 한번만 name이 가공되고 encapsulates 되어 있으니 좋지 않은가? first()가 여러 번 호출된다고 하여도 성능상의 문제도 없다
public final class EnglishName implements Name {
private final CharSequence text;
public EnglishName(final CharSequence txt) {
this.text = txt;
}
@Override
public String first() {
return this.text.toString().split("", 2)[0];
}
}
하지만 위 처럼 생성자의 코드를 없에고 first()에서 처리하는 것이 좋은 디자인이다.
첫번째 예제에서는 모든 연산을 즉시, 바로 처리한다. 이것은 절차적 프로그래밍이다.
하지만 선언적 프로그래밍에서는 모든 연산을 될 수 있는한 delay해야 한다.
아래와 같은 예는 어떤가?
final Name name = new EnglishName(
new NameInPostgreSQL(/*...*/)
);
if (/* something goes wrong */) {
throw new IllegalStateException(
String.format(
"Hi, %s, we can't proceed with your application",
name.first()
)
);
}
첫번째 라인에서 우리는 단지 객체를 만들고 싶을 뿐인데 데이터베이스가 연결되고 fetch된다. 이것은 사이드 이펙트로 볼수 있다. 이 경우 어플리케이션은 더 느려질 것이다.
생성자에서 어떠한 연산을 가져가는 것은 bad practives이고 이것은 사이드이펙트 떄문에 피해야한다.
성능관점에서는 어떤가? name.first()가 다섯번 호출되면 String.split()가 다섯번 호출 될 것이다.
이를 해결하기 위해 우리는 새로운 클래스를 만들어야 한다.
public final class CachedName implements Name {
private final Name origin;
public CachedName(final Name name) {
this.origin = name;
}
@Override
@Cacheable(forever = true)
public String first() {
return this.origin.first();
}
}
Cacheable annotation을 사용했다. Guava Cache나 다른 캐시를 사용 할 수 있을 것이다. 하지만 CachedName을 mutable하게 만들지는 말라. 이것은 Objects Should Be Immutable에서 설명했다.
final Name name = new CachedName(
new EnglishName(
new NameInPostgreSQL(/*...*/)
)
);
이것은 primitive한 예지만 아이디어를 얻길 바란다.
이 디자인에서 우리는 오브젝트를 두개로 나누었다. 생성자에서 유일하게 허락된 구문의 할당임을 강조하고 만약 무엇인가 생성자안에 존재해야 한다면 리펙토링하고 디자인에 대해 다시 생각하라
- Total
- Today
- Yesterday
- shenandoah
- CompressedOops
- kerberos
- SSL
- authentication
- Java
- Dynamodb
- oops
- Certificate Chain
- Consumer
- DESIGN
- JVM
- OOP
- ranking
- Kafka
- GC
- Intermediate Certificate
- AWS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |