ν΄λμ€μ κ°μ²΄
ννλ€ λΆμ΄λΉ΅κ³Ό λΆμ΄λΉ΅ ν, μ€κ³λμ 건물과 κ°μ μμΌλ‘ ν΄λμ€μ κ°μ²΄λ₯Ό μ€λͺ ν΄μλ€. λ μμ λΉμ·ν μμ€μΌλ‘ ν΄λμ€μ μ κ°μ²΄μ λν΄ μ΄ν΄νκ³ μμ λΏμ΄μλ€. λ€λ§, κ·Έλ¬ν μμ€μΌλ‘ ν΄λμ€μ κ°μ²΄μ κ΄κ³μ κ·Έ μ체λ₯Ό μ΄ν΄νλ κ²μ μ ννμ§ λͺ»νλ€.
ν΄λμ€μ μ± μμ κ°μ²΄λ₯Ό μμ±νκ³ , μ μ ν λμ νκ΄΄νλ κ²μ΄λ€. λν ν΄λμ€μ μμλ€μ΄ μ΄λ€ λͺ¨μ΅μ΄λ©° μ΄λ€ νλμ ν΄μΌ νλ μ§ μ μ΄λμ "κ³μ½"μ λν΄μ μκ³ μλ€. κ°μ²΄λ κ³μ½μ λν μ격μ κ°μΆκΈ° μν΄ μΈν°νμ΄μ€λ₯Ό ꡬνν¨μΌλ‘μ¨ μ΄λ₯Ό μ€μνκ² λλ€. λ¬Όλ‘ μΈν°νμ΄μ€λ μΆμνλ₯Ό ν΅ν΄ λ€νμ±μ΄ 보μ₯λ λ€λ μ μμλ μλ―Έκ° μκΈ΄νλ€.
κ°μ²΄λ μλͺ 체μ΄λ€.
μ¬λ°λ₯Έ κ°μ²΄λ κ·Έ μμ²΄λ‘ μλͺ 체μ΄λ€. νμ€ μΈκ³μ νΌμ‘°λ¬Όμ λ리μ κ·Έ μ체μ΄λ©°, μλͺ μ£ΌκΈ°μ νμ, μ΅κ΄μ μ§λ κ²μ΄λ€. μλ₯Ό λ€μ΄, μ§μμ΄λ λΆμ, HTTP μμ²μ΄λ νμΌ λ±μ΄ μ μ ν κ°μ²΄μ΄λ€.
HTTP μμ²μ΄λ νμΌ λ±μ μ»΄ν¨ν°λ₯Ό μΌμΌνλ κ°μμΈκ³μμλ§ μ‘΄μ¬νλ κ²μ΄ μλκ° μκ°ν μ μλ€. κ·Έλμ νμ€μΈκ³μ μ μλ₯Ό μ‘°κΈ λ€λ₯΄κ² μκ°ν΄μΌ νλ€. νμ€μΈκ³λ κ°μ²΄κ° μ΄μκ°λ νλ‘κ·Έλ¨ λ²μμμ μ‘΄μ¬νλ λͺ¨λ κ²μ΄λ€.
μ»΄ν¨ν°μμ νλ‘κ·Έλ¨μ΄ λμνλ κ³³μ΄ μλλΌ, μ€μ νμΌμ΄ μ μ₯λ λμ€ν¬λ νμ€μΈκ³μ΄λ©° νλ‘κ·Έλ¨μμλ λ¨μν μ΄λ₯Ό λνν λΏμ΄λ€.
GoF ν¨ν΄μ λ€λ₯Έ κ°μ²΄μ ν¨κ» μ¬μ©νκΈ° μν ν¨ν΄μ΄λ€. 컨νΈλ‘€λ¬λ μ±κΈν΄, ν©ν°λ¦¬ κ·Έ μμ²΄λ‘ λ³Έλ€λ©΄ μ’μ κ°μ²΄κ° λ μ μλ€. μ΄λ GoF ν¨ν΄μ΄ νμ€μΈκ³μ λνμκ° λ μ μκΈ° λλ¬Έμ΄λ€.
κ°μ²΄λ κ³ μ νλ©°, λΆλ³μ μ΄λ€.
μΊ‘μνλ κ³ μ μ±μ μ§ν€κΈ° μν΄μ νμ°μ μ΄λ€. λ§μ½ 볡μ¬νλ κ²μ΄ κ°λ₯νλ€λ©΄, λμΌν 볡μ λ³Έμ κ°μ§κ² λλ©° μ΄λ λ°λμ§νμ§ μλ€.
κ·Έλ κΈ° λλ¬Έμ μ’μ κ°μ²΄λ μΊ‘μννλ μνλ₯Ό μ§ν€κΈ° μν΄ λΆλ³μ±μ μ μ§νκ³ μ νλ€. κ·Έλ κ² νμ¬ κ°μ²΄λ κ·Έ κ°μ²΄κ° λννλ κ²μ λ°°μ νμ§ μμμΌ νλ€.
@Immutable
final class HTTPStatus implements Status {
private URL page;
public HTTPStatus(URL url) {
this.page = url;
}
@Override
public int read() throws IOException {
return HttpURLConnection.class.cast(
this.page.openConnection()
).getResponseCode();
}
}
_read()_ ν¨μκ° λ€λ₯Έ κ°μ λ°ννλ κ²μ΄ κ°λ₯νλλΌλ, μμ μ΄ λννλ URL μ체λ μ λ λ³νμ§ μμΌλ©° _setter_λ₯Ό ν΅ν΄ λ°°μ νλ μΌ λ°μλ μ‘΄μ¬νμ§ μλλ€.
κ·Έλ λ€λ©΄, λΆλ³μ±μ΄ 보μ₯λλ€λ©΄ μ΄λ€ μ μμ λμ± μ’μκΉ?
- μμ±κ³Ό ν μ€νΈ, κ·Έλ¦¬κ³ μ¬μ©νκΈ° κ°νΈνλ€.
- λΆλ³ κ°μ²΄λ μ€λ λ μμ (Thread Safe)νλ€.
- λΆλ³ κ°μ²΄λ μκ°μ κ²°ν©μ νΌνλλ° λμμ΄ λλ€.
- λΆλ³ κ°μ²΄λ λΆμν¨κ³Ό(side effect)λ₯Ό μΌμΌν€μ§ μλλ€.
- λΆλ³ κ°μ²΄λ μ€ν¨μμμ±(Failure Atomic)μ λλ€.
- μΊμ±νκΈ° μ¬μμ§λ€.
- NULL μ°Έμ‘°λ₯Ό λ°©μ§νλ€.
πΆ λΆλ³ κ°μ²΄λ μ€λ λ μμ νλ€.
μ€λ λ μμ νλ€λ λ§μ΄ μλ―Ένλ λ°λ κ³§, μ¬λ¬ μ€λ λμμ μ κ·Όνμ¬λ μ’λ€λ λ»μ΄λ€. κ·Έλ κ² νμ¬λ μ ν μΆ©λν μΌμ΄ λ°μνμ§ μκΈ° λλ¬Έμ΄λ€.
μ΄λ€ λ©μλλ ν΄λΉ κ°μ²΄μ μνλ₯Ό λ³κ²½ν μ μμΌλ©°, κ° κ°μ²΄λ λ©λͺ¨λ¦¬ κ³΅κ° μμ κ³ μ ν μ리λ₯Ό μ°¨μ§νκ³ μλ€.
πΆ λΆλ³ κ°μ²΄λ μκ°μ κ²°ν©(Temporal Coupling)μ νΌν μ μλ€.
μκ°μ κ²°ν©μ A λ©μλκ° B λ©μλλ³΄λ€ λ°λμ λ¨Όμ νΈμΆν΄μΌ νλ€λ κ²μμ λ°μνλ€. μ΄λ¬ν μνλ μμ μ μμμ μμ‘΄μ±μ΄ μ‘΄μ¬ν¨μ λ§νλ€. λ§μ½ μκ°μ κ²°ν©μ΄ μλ μμ λ€μ λμμ μ²λ¦¬λ μ μλ€. μ¦, λμμ±μ λν κ³ λ―Όμ ν μ μκ³ , λ³΄λ€ λμ μ€κ³λ₯Ό ν΄λΌ μ μλ€. μ΄λ λμ± μ’μ νμ₯ κ°λ₯μ±κ³Ό μ±λ₯μ κ°μ Έμ¨λ€.
λΆλ³ κ°μ²΄λ₯Ό μ¬μ©ν¨μΌλ‘μ¨ μ΄λ¬ν μκ°μ κ²°ν©μ μμ¨ μ μλ€.
πΆ μ€ν¨ μμμ μΈ(Faliure Atomic) λ©μλλ₯Ό λ§λ€ μ μλ€.
κ°λ³ κ°μ²΄λ μμ λμ€ μμΈκ° λ°μνλ©΄, λΆμμ ν μνμ λΉ μ§κ² λλ€. μ΄λ λ λ€λ₯Έ μλ¬λ₯Ό μΌκΈ°ν μ μλ€. λ°λ©΄, λΆλ³ κ°μ²΄λ μ무리 μμΈκ° λ°μνλλΌλ μ΄κΈ° λ©μλ νΈμΆ μ΄μ μ μνλ₯Ό νμ μ μ§ν μ μλ€. λν μμΈκ° λ°μνλλΌλ λ€μ λ‘μ§μ μ²λ¦¬κ° κ°λ₯νλ€.
πΆ λΆμν¨κ³Ό(side effect)λ₯Ό νΌν΄ μ€λ₯λ₯Ό νΌν μ μλ€.
λΆμν¨κ³Όλ λ³μμ κ°, κ°μ²΄μ νλ κ°, μλ£κ΅¬μ‘°κ° λ°λκ±°λ μλ¬λ I/Oκ° λ°μνλ κ²μ μλ―Ένλ€. λ§μ½ _setter_λ₯Ό ν΅ν΄ κ°μ΄ λ³νλλ€λ©΄, μ ν λΆμν¨κ³Όλ₯Ό μ§λμ§ λͺ»νλ©° κ°μ²΄μ μνλ₯Ό μμΈ‘νκΈ° μ΄λ €μΈ κ²μ΄λ€.
λ°λΌμ λΆμν¨κ³Όλ₯Ό μ κ±°ν μμν¨μλ₯Ό λ§λλ κ²μ΄ κ΅μ₯ν μ€μν΄μ§λ€. μ΄λ, κ°μ²΄κ° λΆλ³κ°μ²΄λΌλ©΄ μ΄λ¬ν μμν¨μλ₯Ό λ§λλ λ° μ©μ΄ν΄μ§λ€.
κΈ°λ³Έμ μΌλ‘ λΆλ³κ°μ²΄λ μμ μ΄ λΆκ°λ₯νλ©°, κ°μ²΄λ₯Ό μμ±νκ³ μ¬μ©νλλ° μ¬λ¬κ°μ§ μ νμ΄ μλ€. μ¦, λ©μλλ€λ μμ°μ€λ½κ² λΆμν¨κ³Όκ° μ κ±°λ μμν¨μλ‘ μ΄λ£¨μ΄μ§ κ²μ΄λ€. μ΄λ λ€λ₯Έ ν¨μμ μν΄μ ν΄λΉ κ°μ²΄μ μνκ° λ³ν μ μμμ μλ―Ένλ©° μ€λ₯λ₯Ό μ€μ΄κ³ , μ μ§λ³΄μμ±μ λμΌ μ μλ€.
μ μ λ©μλλ μ§μνμ.
μ μ λ©μλλ κ°μ²΄μ§ν₯ ν¨λ¬λ€μμ λ°νλ μ€κ³μ΄λ€. κ·Έ μ΄μ λ μ μ λ©μλλ₯Ό μ¬μ©ν¨μΌλ‘μ¨, κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ΄ μλλΌ ν΄λμ€μ§ν₯ νλ‘κ·Έλλ°μ λ°λκΈ° λλ¬Έμ΄λ€.
κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ μ¬μ©ν¨μΌλ‘μ¨ μ»μ μ μλ μ΄μ μ κ·Έ "κ³ λ¦½μ±"μ μλ€. κ°μ²΄ μμ μ κ³Όμ μ μννλ λ° μ λ νλ©° μ΄ κ³Όμ μ μμ΄ λ©μλ μ ν¨λ²μλ μ§μλ³μμ ν΄λΉλλ€. λ°λ©΄, μ μ λ©μλλ₯Ό μ¬μ©νκ² λλ©΄ μΈμ λ κ·Έ ν΄λμ€λ μ μ λ³μμ ν΄λΉλλ€.
κ°μ²΄μ μ΄λ¦μμ -erμ νΌνμ.
κ°μ²΄μ μ΄λ¦μ μ§μ λ κ°μ²΄κ° 무μμ νλ μ§λ³΄λ€λ κ°μ²΄κ° 무μμΈ μ§μ μ΄μ μ λμ. "νμ΄μ§ λͺ¨μκΈ°"λΌλ μ΄λ¦λ³΄λ€λ "μ± " μ΄λΌλ μ΄λ¦μ΄ ν¨μ¬ λ λ«λ€λ κ²μ΄λ€.
ν΄λμ€λ finalμ΄λ abstractλ₯Ό μ°μ.
_final_ν΄λμ€λ μμμ ν΅ν΄ νμ₯ν μ μλ ν΄λμ€μ΄λ€. μ¦, λꡬλ _@Override_ λ°μ½λ μ΄μ μ ν΅ν΄μ λ©μλ κΈ°λ₯μ νμ₯ν μ μλ€.
κΈ°λ₯μ νμ₯ν μ μμΌλ©΄ μ½λ μμ±μ λ ν΄λ λμ μ’μ§ μμκΉ? λΌλ μκ°μ΄ λ€ μ μλ€. λ€λ§, κΈ°λ₯ νμ₯ λ©΄μμλ μ’μ μ§ λͺ°λΌλ λΆλͺ¨ ν΄λμ€μ "ꡬνμ μΌλΆ"λ₯Ό μ§μ΄λ£λ μ μ΄κΈ° λλ¬Έμ μλΉν ν° μνμ κ°μν΄μΌ νλ€.
μ¦, _@Override_λ₯Ό ν΅ν΄μ λΆλͺ¨ ν΄λμ€μ λ©μλλ₯Ό κ°μ Έμ λ°κΎΈκ² λλ©΄, ν΄λΉ λΆλͺ¨ ν΄λμ€μ λͺ¨λ λ©μλλ _@Override_λ μμ λ©μλμ μμ‘΄νλ μ μ΄ λλ€. λ§μ½ μ΄λ¬ν μνμμ μμ ν΄λμ€μ λ©μλ λ³κ²½μ΄ μκΈ°κ±°λ, μ μ νμ§ λͺ»νκ² _@Override_λλ€λ©΄ μμΉμλ μ€λ₯κ° λ°μν μλ μλ€.
λ°λ©΄, _final_λ‘ μμ μ체λ₯Ό λ§μλ²λ¦°λ€λ©΄ μ΄λ¬ν λ¬Έμ λ μ½κ² ν΄κ²°ν μ μλ€. κ·Έλ¬λ©΄ _final_ν΄λμ€λ₯Ό νμ₯νλ κ²μ μμ λΆκ°λ₯ν κ²μΌκΉ? μ¬κΈ°μλ "μ‘°ν©"μ μ¬μ©νλ©΄ λλ€.
final class OnlyValidStatus implements Status {
private final Status origin;
public OnlyValidStatus(Status status) {
this.origin = status;
}
@Override
public int read() throws IOException {
int code = this.origin.read();
if (code >= 400) {
throw new RuntimeException("Unsuccessful HTTP code");
}
return code;
}
}
μ΄κΈ°μ μμ±μλ₯Ό ν΅ν΄ _Status_ μΈμ€ν΄μ€λ μ λλ‘ μΊ‘μνλμ΄ λ©€λ²λ³μλ‘ μ μ₯λλ€. μ΄λ κ² μμ λμ λ©€λ²λ³μλ‘μ¨ μμ λμμ λ°κ² λλ©΄, λ©μλλ₯Ό νΈμΆνλ λ°©μμΌλ‘ λμνκΈ° λλ¬Έμ μΊ‘μνλ₯Ό κΉ¨λ¨λ¦¬μ§ μλλ€.
_abstract_ ν΄λμ€λ κ·Έ λ°λμ κ²½μ°μ΄λ€. _abstract_κ° λΆμ ν΄λμ€λ κ·Έ μμ²΄λ‘ μ¬μ©νλ κ²μ΄ λΆκ°λ₯νλ€. 무쑰건 λ³λμ ꡬν λ‘μ§μ λΆμ¬μ£Όμ΄μΌ μλν μ μλ€λ λ§μ΄λ€. μ΄λ, 건λ릴 μ μκ² νμ©ν κ³³μλ§ λ£μ μ μλ€.(_final_μ΄ μλ κ²)
abstract class ValidatedHTTPStatus implements Status {
@Override
public final int read() throws IOException {
int code = this.origin.read();
if (!this.isValid()) {
throw new RuntimeException("Unsuccessful HTTP code");
}
return code;
}
protected abstract boolean isValid();
}
μ μ½λλ _final_κ³Όλ λ¬λ¦¬, μ μ ν λΆλΆμ μμ΄μ λ‘μ§μ μ£Όμ ν΄μ£ΌκΈ°λ₯Ό μνκ³ μλ€. κ·Έ μΈμ 건λλ¦¬μ§ μμμΌ ν λ©μλλ finalμ ν΅ν΄ _@Override_λΉνλ κ²μ λ§μμΌλ‘μ¨ λ°©μ΄ν΄ μ€ μ μλ€.