π μ£Όμ
κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μλ 'SOLID' μμΉμ΄ μλ€. Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion μ΄ 5κ°μ§ μμΉμ λ§νλλ° μμΈν μμμ ν¨κ» 5κ°μ κ°λ μ λͺ¨λ λ³΄κ³ μ νλ€.
β S: λ¨μΌ μ± μ μμΉ(SRP)
λ¨μΌ μ± μ μμΉ(Single Responsibility, SRP)λ "ν΄λμ€λ νλμ μ± μλ§ κ°μ ΈμΌ νλ€"λ μμΉμ΄λ€.
- μ± μ: ν΄λμ€κ° μ²λ¦¬ν΄μΌ νλ νλμ λ³κ²½ μ΄μ
μ½κ²λ ν΄λμ€κ° λ΄λΉν΄μ μ²λ¦¬ν΄μΌ νλ νλμ "μΌ"μ΄λΌκ³ λ³Ό μ μλ€. ν΄λμ€λ μμ μ΄ λ§‘μ νΉμ ν "μΌ"λ§ μ²λ¦¬ν΄μΌ νλ€. νλμ ν΄λμ€λ λ¨ νκ°μ§μ μ΄μ λ‘λ§ λ³κ²½λμ΄μΌ νλ€.
νλμ ν΄λμ€κ° λ§‘λ μ± μμ΄ λ§μμ§μλ‘, ν΄λμ€λ 볡μ‘ν΄μ§κ³ μμ κ³Ό μ μ§λ³΄μκ° μ΄λ €μμ§λ€. ν μΌμ λ³κ²½νλ€κ° λ€λ₯Έ μΌμ μν₯μ λΌμΉ μ μκΈ° λλ¬Έμ΄λ€.
β μμ
μΌμμνμ μμλ‘ μκ°ν΄λ³΄μ.
μΉ΄νμμ μ§μμ΄ ν λͺ λ§ μλ€. μ΄ μ§μμ 컀νΌλ₯Ό μ μ‘°νκ³ , κ³μ°λ νκ³ , μ²μλ νλ€.
ν λͺ μ μ§μμ΄ μ¬λ¬ μ 무λ₯Ό λ§‘κ³ μλ€. λ§μ½ μ»€νΌ μ μ‘° λ μνΌκ° λ°λκ³ , ν¬μ€κΈ° μμ€ν λ λ°λκ³ , μ²μ ꡬμλ λ°λλ€λ©΄ μ μνκΈ° μ½μ§ μμ κ²μ΄λ€.
- μ§μ=ν΄λμ€, μ 무=μ± μ, λ μνΌ, μμ€ν , ꡬμ λ°λ=λ³κ²½ μ΄μ , μ μ=ν΄λμ€ μμ /λ³κ²½μ΄λΌκ³ μκ°ν΄λ³΄μ.
μΉ΄νμ μ§μμ΄ λμλ€. λ°λ¦¬μ€νλ 컀νΌλ₯Ό λ§λ€κ³ , μΊμ λ κ³μ°μ νκ³ , μ²μλΆλ μ²μλ₯Ό νλ€.
μ»€νΌ λ©λ΄κ° λ°λμ΄λ μΊμ μ μ²μλΆλ μ κ²½μ°μ§ μλλ€. ν¬μ€κΈ° μμ€ν μ΄ λ°λμ΄λ λ°λ¦¬μ€νμ μ²μλΆλ μ κ²½μ°μ§ μλλ€. μμ μ μ± μμ΄ μλκΈ° λλ¬Έμ΄λ€.
μ 무 λΆμ₯(=μ± μμ λλλ κ²)μ΄ ν¨μ¨μ μ΄κ³ μμ μ μΈ μ΄μμ μν ν΄λ΅μ΄λ€.
π₯οΈ μμ μ½λ
- λ¨μΌ μ± μ μμΉμ μ§ν€μ§ μμ κ²½μ°
μ»€νΌ μ μ‘°μ μ£Όλ¬Έ λ°κΈ°, λ κ°μ§ μΌμ νκ³ μλ€. μ΄ ν΄λμ€λ μλ£ λ μνΌκ° λ°λκ±°λ, λλ νκΈλ§ λ°λ λ± κ²°μ μμ€ν μ΄ λ°λλ λ± λ κ°μ§μ μ΄μ λ‘ λ³κ²½λ μ μλ€.
public class Cafe {
// μ»€νΌ μ μ‘°
public Coffee makeCoffee(String menu) {
if(λ©λ΄=="μλ©λ¦¬μΉ΄λ
Έ") {
μλ μΆμΆ;
λ¬Ό λ°λ₯΄κΈ°;
} else if(λ©λ΄=="μΉ΄νλΌλΌ") {
μλ μΆμΆ;
μ°μ μ€ννκΈ°;
}
...
}
// μ£Όλ¬Έ λ°κΈ°
public void createOrder(String menu) {
ν¬μ€κΈ°μμ λ©λ΄ μ ν;
...
}
}
- λ¨μΌ μ± μ μμΉμ μ§ν¨ κ²½μ°
λ°λ¦¬μ€νλ μ»€νΌ μ μ‘°λ₯Ό, μΊμ λ κ²°μ λ₯Ό μ²λ¦¬νλ€.
public class Barista {
// μ»€νΌ μ μ‘°
public Coffee makeCoffee(String menu) {
if(λ©λ΄=="μλ©λ¦¬μΉ΄λ
Έ") {
μλ μΆμΆ;
λ¬Ό λ°λ₯΄κΈ°;
} else if(λ©λ΄=="μΉ΄νλΌλΌ") {
μλ μΆμΆ;
μ°μ μ€ννκΈ°;
}
...
}
}
public class Casher {
// μ£Όλ¬Έ λ°κΈ°
public void createOrder(String menu) {
ν¬μ€κΈ°μμ λ©λ΄ μ ν;
...
}
}
κ°κ°μ ν΄λμ€κ° λͺ ννκ² μμ λ§μ μ± μμ κ°μ§λ―λ‘ ν μ€νΈ, μμ , μ μ§λ³΄μκ° μ¬μ°λ©° λ 립μ μ΄λ―λ‘ μ¬μ¬μ©λ μ½λ€.
β O: κ°λ°©-νμ μμΉ(OCP)
κ°λ°©-νμ μμΉ(Open-Closed)μ νμ₯μλ μ΄λ € μμ΄μΌ νκ³ , λ³κ²½μλ λ«ν μμ΄μΌ νλ€λ μμΉμ΄λ€.
μλ.. λ¨μΌ μ± μ μμΉμμλ μμ νκΈ° μ¬μμ§λ€λ©΄μμ? λ³κ²½μλ λ«ν μλ€λ, μμ νμ§ λ§λΌλ 건κ°μ?
μ΄ μμΉμ λͺ¨λ λ³κ²½μ λν΄ λ§νλ κ² μλλ€. νμ₯λ λμ λ³κ²½μ λ§νλ€.
κΈ°μ‘΄μ μ½λλ₯Ό λ³κ²½νμ§ μμΌλ©΄μλ μμ€ν μ κΈ°λ₯μ νμ₯ν μ μμ΄μΌ νλ€. κ°λ°©-νμ μμΉμ λ°λ₯΄λ©΄, μλ‘μ΄ κΈ°λ₯μ μΆκ°ν λ κΈ°μ‘΄μ μ½λμ μν₯μ μ£Όμ§ μκ³ λ μΆκ°ν μ μμ΄μΌ νλ€.
μμ§λ, μ΄λ―Έ μ λμκ°λ κΈ°μ‘΄ μ½λλ₯Ό νμ₯νλ€κ³ 건λ€μ΄μ§ λ§κ³ μλ‘μ΄ μꡬμ¬νλ§ κ΅¬ννλΌλ λ»μ΄λ€.
μ΄λ μ΄μ©νκΈ° μ’μ κ²μ΄ μΆμνμ μΈν°νμ΄μ€λ€. μμ μ½λλ‘ λ³΄μ.
πͺ μμ μ½λ
- κ°λ°© νμ μμΉμ μ§ν€μ§ μμ κ²½μ°
κ²°μ μ κ³ κ°μ΄ μ§λΆν΄μΌ νλ κ°κ²©μ μλ €μΌ νλ€.
public class Casher {
// κ°κ²© μ°ΎκΈ°
public int getPrice(String menu) {
if(λ©λ΄==μλ©λ¦¬μΉ΄λ
Έ)
return 2000;
else if(λ©λ΄==μΉ΄νλΌλΌ)
return 3000;
else if ...
}
}
λ§μ½ μ¬κΈ°μμ μ λ©λ΄ λ²λΈν°κ° μΆκ°λλ€λ©΄? else if()μ μΆκ°ν΄μΌ ν κ²μ΄λ€. μ λ©λ΄λ‘ νμ₯λμ§λ§ κΈ°μ‘΄ μ½λκ° λ³κ²½λλ κ²μ΄λ€.
- κ°λ°© νμ μμΉμ μ§ν¨ κ²½μ°
λ©λ΄κ° λͺ κ°κ° μΆκ°λλ κΈ°μ‘΄μ μ½λλ€μ λ³νμ§ μλλ€.
interface Drink {
int getPrice();
}
class Americano {
public int getPrice() { return 2000; }
}
class CafeLatte {
public int getPrice() { return 3000; }
}
class BubbleTea {
public int getPrice() { return 5000; }
}
κ°λ°©-νμ μμΉμ μ μ°νκ² νμ₯μ΄ κ°λ₯νλ©΄μλ κΈ°μ‘΄ μ½λλ₯Ό 건λλ¦¬μ§ μμΌλ―λ‘ μμ μ μ΄λ€.
β L: 리μ€μ½ν μΉν μμΉ(LSP)
리μ€μ½ν μΉν μμΉ(Liskov Substitution)μ μλΈ νμ μ μΈμ λ κ·Έκ²μ λ² μ΄μ€ νμ μΌλ‘ μΉνλ μ μμ΄μΌ νλ€λ μμΉμ΄λ€.
- μλΈ νμ = μμ ν΄λμ€
- λ² μ΄μ€ νμ = λΆλͺ¨ ν΄λμ€
λΆλͺ¨ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μ¬μ©νλ μ½λκ° μμ ν΄λμ€λ‘ λ체λλλΌλ νλ‘κ·Έλ¨ λμμ λ¬Έμ κ° μμ΄μΌ νλ€λ μλ―Έλ‘ λ€νμ±μ μμ μ±μ 보μ₯νλ μμΉμ΄λ€. λΆλͺ¨ ν΄λμ€μ λμ κ²°κ³Όκ° κ°μμΌ νλ€κΈ° 보λ€λ, "λΆλͺ¨ ν΄λμ€μ κ·μΉμ κΉ¨μ§ λ§λΌ"κ° ν΅μ¬μ΄λ€.
ποΈ μμ μ½λ
- 리μ€μ½ν μΉν μμΉμ μ§ν€μ§ μμ κ²½μ°
λΆλͺ¨ ν΄λμ€ Birdλ μμ λΉν λμμ μ μνλ€. μ΄ ν΄λμ€μμμ μ§μΌμ ΈμΌ νλ κ·μΉμ "μλ λ μ μλ€"μ΄λ€. μμ ν¬ν¨λλ Penguinμ μμ ν΄λμ€λ‘ λΉν λμμ ꡬνν΄μΌ νλ€.
κ·Έλ°λ° νκ·μ λ μ μλ μλ€! Penguinμμλ λΉν λμμ μ λλ‘ κ΅¬νν μ μλ€. Bird μΈμ€ν΄μ€λ₯Ό Penguin μΈμ€ν΄μ€λ‘ λ°κΎΈλ©΄ "μλ λ μ μλ€"λ κ·μΉμ μ§ν¬ μ μλ€.
public abstact class Bird {
public void fly() {
System.out.println("λ μκ°λλ€.");
}
}
public class Penguin extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("νκ·μ λ μ μμ΅λλ€.");
}
}
public class Main {
public static void main(String[] args) {
Bird bird = new Bird();
bird.fly(); // "λ μκ°λλ€."
Bird penguin = new Penguin();
penguin.fly(); // UnsupportedOperationException μμΈ λ°μ
}
}
- 리μ€μ½ν μμΉμ μ§ν¨ κ²½μ°
νκ·μ΄λΌλ λ°λ‘λ₯Ό λ°κ²¬νμΌλ λΆλͺ¨ ν΄λμ€μ "μλ λ μ μλ€"λ κ·μΉμ 깨보μ. λ€νν μλ€ λͺ¨λ μ΄λ»κ²λ μμ§μΌ μλ μλ€. "μλ μμ§μΈλ€"λ κ²μ μ μ λ‘ "λ μ μλ μ"μ "μμ§μ΄λ μ(λ μ μλ μ)"λ‘ λΆλ¦¬ν΄λ³΄μ.
μλ μμμμλ FlyingBirdμ Penguin ν΄λμ€κ° λΆλͺ¨μ ν΄λμ€ Birdμ κ·μΉ "μλ μμ§μΈλ€"λ₯Ό μ μ§ν€κ³ , λ©μΈ ν΄λμ€μμ Bird μΈμ€ν΄μ€λ₯Ό FlyingBird, Penguin μΈμ€ν΄μ€λ‘ λ°κΏλ λ¬Έμ μμ΄ λμνλ€.
// μμ κ³΅ν΅ λμμ μ μνλ μμ ν΄λμ€
abstract class Bird {
public abstract void move(); // λͺ¨λ μκ° μ΄λν μ μμ
}
// λ μ μλ μ
class FlyingBird extends Bird {
public void fly() {
System.out.println("λ μκ°λλ€!");
}
@Override
public void move() {
fly(); // λ μ μ΄λ
}
}
// νκ·μ λ μ§ λͺ»νλ μ
class Penguin extends Bird {
@Override
public void move() {
System.out.println("ν€μμΉ©λλ€!");
}
}
public class Main {
public static void main(String[] args) {
Bird sparrow = new FlyingBird(); // μ°Έμλ λ μ μμ
sparrow.move(); // "λ μκ°λλ€!"
Bird penguin = new Penguin(); // νκ·μ ν€μμΉ¨
penguin.move(); // "ν€μμΉ©λλ€!"
}
}
리μ€μ½ν μΉν μμΉμ μ§ν€λ©΄ λ€νμ±μ νμ©ν μ½λμμ λ¬Έμ λ°μμ λ°©μ§ν μ μλ€. λΆλͺ¨ ν΄λμ€μ κ·μΉμ μλ°ν μμ ν΄λμ€μ μμνμ§ λͺ»ν μ€λ₯λ₯Ό λ§μ.
β I: μΈν°νμ΄μ€ λΆλ¦¬ μμΉ(ISP)
μΈν°νμ΄μ€ λΆλ¦¬ μμΉ(Interface Segregation)μ μΈν°νμ΄μ€λ ν΄λΌμ΄μΈνΈκ° μ¬μ©νμ§ μλ λ©μλμ μμ‘΄νμ§ μλλ‘ μ€κ³ν΄μΌ νλ€λ μμΉμ΄λ€.
- μμ‘΄μ΄λ? ν ν΄λμ€λ λͺ¨λμ΄ λ€λ₯Έ ν΄λμ€λ λͺ¨λμ νμν μμμ μ¬μ©νκ±°λ κΈ°λ₯μ μννκΈ° μν΄ ν΄λΉ ν΄λμ€λ λͺ¨λμ μ§μ μ μΈ μν₯μ λ°λ κ΄κ³μ΄λ€.
νλμ ν° μΈν°νμ΄μ€λ₯Ό μ¬λ¬ κ°μ μμ μΈν°νμ΄μ€λ‘ λλ μ, νΉμ ν΄λΌμ΄μΈνΈκ° μμ μκ² νμ μλ κΈ°λ₯μ ꡬννμ§ μκ³ , μμ μ΄ νμν κΈ°λ₯λ§ μ¬μ©ν μ μλλ‘ νμ.
λ°λ‘ μμλ₯Ό 보λ κ² λ«λ€.
π¨οΈ μμ μ½λ
- μΈν°νμ΄μ€ λΆλ¦¬ μμΉμ μ§ν€μ§ μμ κ²½μ°
νλ¦°νΈ, μ€μΊ, ν©μ€ κΈ°λ₯μ΄ μλ 볡ν©κΈ°κ° μλ€. μ΄ λ³΅ν©κΈ°λ‘λΆν° μ λν νλ¦°ν°λ₯Ό νλ λ§λ€κ³ μΆλ€. νλ¦°ν°μλ μ€μ§ νλ¦°νΈ κΈ°λ₯λ§ μλ€.
SimplePrinter ν΄λμ€λ μ€μ§ νλ¦°ν°λ‘μλ§ λμνλ©΄ λλλ° Device μΈν°νμ΄μ€ λλ¬Έμ μκΈ°μκ² νμλ μλ μ€μΊκ³Ό ν©μ€κΉμ§ ꡬνν΄μΌ νλ€. κ²°κ³Όλ λΉμ°ν μμΈ λ°μμ΄λ€.
public interface Device {
void print(String content);
void scan(String content);
void fax(String content);
}
//νλ¦°ν°λ νλ¦°νΈ λ°μ λͺ»νλλ° μ€μΊκ³Ό ν©μ€λ λ°λμ ꡬνν΄μΌ ν¨
public class SimplePrinter implements Device {
@Override
public void print(String content) {
System.out.println("Printing: " + content);
}
@Override
public void scan(String content) {
throw new UnsupportedOperationException("Scan not supported by this device.");
}
@Override
public void fax(String content) {
throw new UnsupportedOperationException("Fax not supported by this device.");
}
}
- μΈν°νμ΄μ€ λΆλ¦¬ μμΉμ μ§ν¨ κ²½μ°
DeviceλΌλ νλμ ν° μΈν°νμ΄μ€λ₯Ό μͺΌκ°μ. λ€μν ν΄λΌμ΄μΈνΈκ° κ°μ νμν μΈν°νμ΄μ€λ§ ꡬνν μ μλ€.
// μΈν°νμ΄μ€ λΆλ¦¬
public interface Fax {
void fax(String content);
}
public interface Printer {
void print(String content);
}
public interface Scanner {
void scan(String content);
}
//λ¨μ νλ¦°ν°
public class SimplePrinter implements Printer{
@Override
public void print(String content) {
System.out.println("Printing : " + content);
}
}
// 볡ν©κΈ°
public class MultifunctionDevice implements Printer, Scanner, Fax{
@Override
public void print(String content) {
System.out.println("MultiDevice printing: " + content);
}
@Override
public void scan(String content) {
System.out.println("MultiDevice scanning: " + content);
}
@Override
public void fax(String content) {
System.out.println("MultiDevice faxing: " + content);
}
}
ν΄λΌμ΄μΈνΈκ° λΆνμν λ©μλ ꡬνμ κ°μ λ°μ§ μκ³ , ν° μΈν°νμ΄μ€λ₯Ό μμ ν λ, μ¬μ©νμ§ μλ ν΄λΌμ΄μΈνΈμλ μν₯μ λ―ΈμΉ κ°λ₯μ±μ΄ μ€μ΄λ€κΈ° λλ¬Έμ ν΄λμ€ κ° μμ‘΄μ±λ κ°μνλ€.
β D: μμ‘΄ μμ μμΉ(DIP)
μμ‘΄ μμ μμΉ(Dependency Inversion)μ κ³ μμ€ λͺ¨λμ μ μμ€ λͺ¨λμ μμ‘΄ν΄μλ μ λλ©°, λ λ€ μΆμν μΈν°νμ΄μ€μ μμ‘΄ν΄μΌ νλ€λ μμΉμ΄λ€.
- κ³ μμ€κ³Ό μ μμ€? κ³ μμ€ λͺ¨λμ μμ€ν μ λΉμ¦λμ€ λ‘μ§κ³Ό μ λ°μ μΈ λμμ μ€κ³νλ μΆμμ μΈ λΆλΆμ΄λ€. μ μμ€ λͺ¨λμ λ°μ΄ν° μ μ₯, νλμ¨μ΄μμ μνΈμμ© λ± μμ λͺ¨λμ΄ μνλ μ€μ§μ μΈ μμ μ μννλ ꡬ체μ μΌλ‘ ꡬννλ λͺ¨λμ΄λ€.
π μμ μ½λ 1
μ£Όλ¬Έμ μ²λ¦¬νκ³ λ°μ΄ν°λ² μ΄μ€μ μ£Όλ¬Έ λ°μ΄ν°λ₯Ό μ μ₯νμ.
- μμ‘΄ μμ μμΉμ μ§ν€μ§ μμ κ²½μ°
OrderService ν΄λμ€λ 'μ£Όλ¬Έ'μ΄λΌλ λΉμ¦λμ€ λ‘μ§μ μ²λ¦¬νλ κ³ μμ€ λͺ¨λμ΄λ€. MySQLOrderRepository ν΄λμ€λ μ£Όλ¬Έ λ°μ΄ν°λ₯Ό μ€μ§μ μΌλ‘ μ μ₯νκΈ° μν μ μμ€ λͺ¨λμ΄λ€.
λ§μ½ λ°μ΄ν°λ² μ΄μ€λ₯Ό λ°κΎΈκ³ μΆλ€λ©΄, MySQL λ°μ΄ν°λ² μ΄μ€μ μμ‘΄νλ κ³ μμ€ λͺ¨λOrderService ν΄λμ€λ₯Ό μμ ν΄μΌ νλ€.
// μ μμ€ λͺ¨λ -> λ°μ΄ν°λ² μ΄μ€(MySQL)λ₯Ό μ¬μ©νμ¬ λ°μ΄ν°λ₯Ό μ μ₯
// ꡬ체μ μΈ μ μ₯ λ°©μ(λ°μ΄ν°λ² μ΄μ€ κΈ°μ )μ ꡬνν ν΄λμ€
public class MySQLOrderRepository {
public void save(String orderData) {
System.out.println("[MySQL] Order saved: " + orderData);
}
}
// μ£Όλ¬Έμ΄λΌλ λΉμ¦λμ€ λ‘μ§μ ꡬνν κ³ μμ€ λͺ¨λ
public class OrderService {
// κ³ μμ€ λͺ¨λμΈλ°, μ μμ€μ μμ‘΄
// : MySQLμ΄λΌλ νΉμ DBμ λν΄μλ§ μν₯μ λ°μ. λ§μ½ DB μ’
λ₯κ° λ°λλ©΄ OrderService μ½λλ₯Ό μμ ν΄μΌ ν¨.
private MySQLOrderRepository repository = new MySQLOrderRepository();
public void createOrder(String orderData) {
System.out.println("Creating order...");
repository.save(orderData); // ꡬ체 ν΄λμ€μ μμ‘΄
}
}
public class Main {
public static void main(String[] args) {
OrderService orderService = new OrderService();
orderService.createOrder("Order #1234");
}
}
- μμ‘΄ μμ μμΉμ μ§ν¨ κ²½μ°
λ°μ΄ν°λ² μ΄μ€μ μ£Όλ¬Έ λ°μ΄ν°λ₯Ό μ μ₯νλ κ²μ μΈν°νμ΄μ€λ‘ λ°κΎΈμ. μΈν°νμ΄μ€ OrderRepositoryλ₯Ό ꡬννλ ν΄λμ€λ€μ΄ κ° λ°μ΄ν°λ² μ΄μ€ λͺ¨λμ΄λ€. OrderServiceλ μ΄ μΈν°νμ΄μ€λ§ μ΄μ©νλ©΄ λκ³ , λ©μΈ ν΄λμ€μμ μμ‘΄μ±μ μ£Όμ νλ©΄ λλ€. μλ‘μ΄ λ°μ΄ν°λ² μ΄μ€λ₯Ό μΆκ°ν΄λ, λ°μ΄ν°λ² μ΄μ€λ₯Ό λ°κΎΈκ³ μΆμ΄λ OrderServiceλ μμ νμ§ μμλ λλ€.
//μΆμν κ³μΈ΅
public interface OrderRepository {
void save(String orderData);
}
// MySQL μ μμ€ λͺ¨λ
public class MySQLOrderRepository implements OrderRepository{
@Override
public void save(String orderData) {
System.out.println("[MYSQL] order saved: " + orderData);
}
}
//OracleDB μ μμ€ λͺ¨λ
public class OracleOrderRepository implements OrderRepository{
@Override
public void save(String orderData) {
System.out.println("[ORACLE] order saved: " + orderData);
}
}
public class OrderService {
// κ³ μμ€ λͺ¨λ
// μΆμ μΈν°νμ΄μ€μ μμ‘΄
private OrderRepository repository;
// μμ±μ μ£Όμ
public OrderService(OrderRepository repository) {
this.repository = repository;
}
public void createOrder(String orderData) {
System.out.println("Creating order >>>");
repository.save(orderData);
}
}
public class Main {
public static void main(String[] args) {
// MySQL μ¬μ©
OrderRepository mySql = new MySQLOrderRepository();
OrderService mySqlOrder = new OrderService(mySql);
mySqlOrder.createOrder("Order from MYSQL DB");
// Oracle λ‘ κ΅μ²΄
OrderRepository oracle = new OracleOrderRepository();
OrderService oracleOrder = new OrderService(oracle);
oracleOrder.createOrder("Order from ORACLE DB");
}
}
π© μμ μ½λ 2
κ³ κ°μκ² μ μν μλ¦Όμ 보λ΄μ. μλ¦Όμ μ΄λ©μΌκ³Ό λ¬Έμ(SMS)λ‘ λ³΄λΌ μ μλ€.
- μμ‘΄ μμ μμΉμ μ§ν€μ§ μμ κ²½μ°
NotificationService ν΄λμ€λ κ³ κ°μκ² λ κ°μ§ λ°©μμΌλ‘ μλ¦Όμ 보λ΄λ 'μλ¦Ό μ μ‘' κΈ°λ₯μ ꡬνν΄μΌ νλ€. EmailSenderμ SmsSender ν΄λμ€λ κ°κ° μ€μ λ‘ κ³ κ°μκ² μ΄λ©μΌ λλ λ¬Έμλ₯Ό 보λΈλ€.
λ§μ½ λͺ¨λ°μΌ μ΄νλ‘λ 보λ΄λ €λ©΄, ν΄λΉ ν΄λμ€λ₯Ό λ§λ€κ³ NotificationServiceμμ μΈμ€ν΄μ€λ₯Ό λ§λ€κ³ , sendNotification() λ©μλλ₯Ό μμ ν΄μΌ νλ€.
class EmailSender {
public void sendEmail(String message) {
System.out.println("μ΄λ©μΌ μ μ‘: " + message);
}
}
class SmsSender {
public void sendSms(String message) {
System.out.println("SMS μ μ‘: " + message);
}
}
class NotificationService {
private EmailSender emailSender = new EmailSender();
private SmsSender smsSender = new SmsSender();
public void sendNotification(String message) {
emailSender.sendEmail(message);
smsSender.sendSms(message);
}
}
public class Main {
public static void main(String[] args) {
NotificationService notificationService = new NotificationService();
notificationService.sendNotification("μμ‘΄ μμ μμΉ ν
μ€νΈ");
}
}
- μμ‘΄ μμ μμΉμ μ§ν¨ κ²½μ°
λͺ¨λ μ€μ§μ μΈ μλ¦Ό μ μ‘ μ μμ€ λͺ¨λμ΄ μΈν°νμ΄μ€ MessageSenderλ₯Ό ꡬννλ€. κ³ μμ€ λͺ¨λ NotificationService ν΄λμ€λ λͺ¨λ°μΌ μ΄ν μλ¦ΌκΉμ§ μΆκ° λμ΄λ μ½λλ₯Ό μμ ν νμκ° μλ€.
// μΆμν: μλ¦Ό λ°μ‘ μΈν°νμ΄μ€
interface MessageSender {
void send(String message);
}
// ꡬ체μ ꡬν: μ΄λ©μΌ λ°μ‘
class EmailSender implements MessageSender {
@Override
public void send(String message) {
System.out.println("μ΄λ©μΌ μ μ‘: " + message);
}
}
// ꡬ체μ ꡬν: SMS λ°μ‘
class SmsSender implements MessageSender {
@Override
public void send(String message) {
System.out.println("SMS μ μ‘: " + message);
}
}
// ꡬ체μ ꡬν: λͺ¨λ°μΌ μ΄ν μλ¦Ό
class AppSender implements MessageSender {
@Override
public void send(String message) {
System.out.println("μ± μλ¦Ό: " + message);
}
}
// μμ λͺ¨λ: μλ¦Ό μλΉμ€
class NotificationService {
private final List<MessageSender> senders;
public NotificationService(List<MessageSender> senders) {
this.senders = senders;
}
public void sendNotification(String message) {
senders.forEach(sender -> sender.send(message));
}
}
public class Main {
public static void main(String[] args) {
// νμν λ°μ‘ λ°©μμ μΆκ°
List<MessageSender> senders = Arrays.asList(new EmailSender(), new SmsSender(), new AppSender());
NotificationService notificationService = new NotificationService(senders);
notificationService.sendNotification("μμ‘΄ μμ μμΉ ν
μ€νΈ");
}
}
μ΄μ²λΌ ꡬ체μ μΈ κ΅¬νμ΄ λ³κ²½λμ΄λ λ μ΄μ κ³ μμ€ λͺ¨λμ μ½λλ λ³νμ§ μλλ€. κ³ μμ€ λͺ¨λμ΄ μΈν°νμ΄μ€μ μμ‘΄νκ³ , μ μμ€ λͺ¨λμ μμ‘΄νμ§ μλλ€.
π μμ½
- λ¨μΌ μ±
μ μμΉ
- "ν΄λμ€λ νλμ μ± μλ§ κ°μ ΈμΌ νλ€."
- νλμ ν΄λμ€λ λ¨ νκ°μ§μ μ΄μ λ‘λ§ λ³κ²½λμ΄μΌ νλ€.
- β μ μ§λ³΄μ: μ½λ λ³κ²½μ΄ νμν μ΄μ κ° λΆλ¦¬λκ³ λͺ ννμ¬ μμ μ΄ μ½λ€.
- β μ¬μ¬μ©μ±: κ° ν΄λμ€κ° λ 립μ μ΄λ―λ‘ λμ€μ ν΄λΉ κΈ°λ₯μ΄ νμν μν©μμ μ½κ² μ¬μ¬μ©μ΄ κ°λ₯νλ€.
- β ν μ€νΈ: ν κ°μ§ μΌμ μνλμ§ ν μ€νΈνλ©΄ λλ μ½λ€.
- κ°λ°©-νμ μμΉ
- "νμ₯μλ μ΄λ € μμ΄μΌ νκ³ , λ³κ²½μλ λ«ν μμ΄μΌ νλ€."
- β μμ μ±: κΈ°μ‘΄ μ½λλ₯Ό 건λλ¦¬μ§ μμΌλ, μ΄λ―Έ μ λμκ°λ κΈ°λ₯μ μλ¬κ° λμ§ μλλ€.
- β μ μ°μ±, νμ₯μ±: μλ‘μ΄ κΈ°λ₯μ μ½κ² μΆκ°νκΈ° νΈνλ€.
- μΆμνμ μΈν°νμ΄μ€λ₯Ό μ νμ©νμ!
- 리μ€μ½ν μΉν μμΉ
- "μλΈνμ μ μΈμ λ κ·Έκ²μ λ² μ΄μ€νμ μΌλ‘ κ΅μ²΄ν μ μμ΄μΌ νλ€."
- μμ ν΄λμ€λ λΆλͺ¨ ν΄λμ€μ κΈ°λ₯μ λ체νλλΌλ λμν΄μΌ νλ€.
- β λ€νμ±μ μμ μ±: λΆλͺ¨ ν΄λμ€μ κ·μΉμ μμ ν΄λμ€λ μ§μΌμ λ€νμ±μ μ§ν€μ. λ€νμ±μ νμ₯κ³Ό μ μ§λ³΄μλ₯Ό μν μ μ©ν κ°λ μ΄λ€.
- μΈν°νμ΄μ€ λΆλ¦¬ μμΉ
- "ν΄λΌμ΄μΈνΈλ μμ μ΄ μ¬μ©νμ§ μλ λ©μλμ μμ‘΄νμ§ μμμΌ νλ€."
- νλμ ν° μΈν°νμ΄μ€λ₯Ό μ¬λ¬ κ°μ μμ μΈν°νμ΄μ€λ‘ λλ μ, νΉμ ν΄λΌμ΄μΈνΈκ° μμ μ΄ νμν κΈ°λ₯λ§ μ¬μ©ν μ μλλ‘ μ€κ³νμ.
- β μ μ§λ³΄μ: ν° μΈν°νμ΄μ€λ₯Ό μμ ν λ, μ¬μ©νμ§ μλ ν΄λΌμ΄μΈνΈμ μν₯μ΄ κ°μ§ μλλ€.
- β μ μ°μ±: ν΄λΌμ΄μΈνΈκ° κ°μ νμν μΈν°νμ΄μ€λ§ ꡬνν μ μλ€.
- μμ‘΄ μμ μμΉ
- "κ³ μμ€ λͺ¨λμ μ μμ€ λͺ¨λμ μμ‘΄ν΄μλ μ λλ©°, λ λ€ μΆμνλ μΈν°νμ΄μ€μ μμ‘΄ν΄μΌ νλ€."
- κ³ μμ€ λͺ¨λ: λΉμ¦λμ€ λ‘μ§κ³Ό μ λ°μ μΈ λμμ μ€κ³νλ λͺ¨λ
- μ μμ€ λͺ¨λ: μμ λͺ¨λμ΄ μνλ μ€μ§μ μΈ μμ μ μννλ ꡬ체μ μΌλ‘ ꡬννλ λͺ¨λ
- β μ μ§λ³΄μμ±: μ μμ€ λͺ¨λμ ꡬ체μ μΈ κ΅¬νμ΄ λ³κ²½λλ κ³ μμ€ λͺ¨λμ μν₯λ°μ§ μλλ€.
- β νμ₯μ±: κ³ μμ€ λͺ¨λμ ꡬννκΈ° μν΄ μλ‘μ΄ μ μμ€ λͺ¨λμ΄ νμν΄λ μΈν°νμ΄μ€λ₯Ό μ΄μ©νλ©΄ κ³ μμ€ λͺ¨λμ μμ ν νμκ° μλ€.
μ΄μ²λΌ SOLID μμΉμ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ λμ± ν¨κ³Όμ μΌλ‘ μννκΈ° μν μμΉμΌλ‘ μ΄λ£¨μ΄μ Έ μλ€. νμ§λ§ μ격ν μ§μΌμΌ νλ μμΉλ³΄λ€λ μ μ ν μν©μ λ§κ² νμ©νλ "λꡬ"λΌλ κ²μ μμ§ μμμΌ νλ€. 무쑰건μ μΈ μμΉ μ μ©λ³΄λ€λ μ μ΄ μμΉμ μ μ©ν΄μΌ ν κΉ?λ₯Ό κ³ λ―Όν΄λ³΄κΈ°λ₯Ό.