๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ํํธ์จ์ด ๊ฐ๋ฐ์์ ๋๋ฆฌ ์ฌ์ฉ๋๋ ํจ๋ฌ๋ค์ ์ค ํ๋์ ๋๋ค. ์ด๋ ๋ฐ์ดํฐ์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ฅผ ๊ฐ์ฒด๋ผ๋ ๋จ์๋ก ๋ฌถ์ด์ ํ๋ก๊ทธ๋๋ฐํ๋ ๋ฐฉ์์ ๋งํฉ๋๋ค.
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํต์ฌ์ ์ค์ ์ธ๊ณ์ ์ฌ๋ฌผ์ ๋ชจ๋ธ๋งํ์ฌ ์ํํธ์จ์ด ๋ด์์ ์ฌํํ๋ ๋ฐ ์์ผ๋ฉฐ, ๊ฐ์ฒด ์งํฅ ์ค๊ณ ์์น์ธ SOLID๋ ์ด๋ฌํ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ณด๋ค ํจ๊ณผ์ ์ผ๋ก ์ํํ๊ธฐ ์ํ ์ง์นจ์ ์ ๊ณตํฉ๋๋ค.
S: ๋จ์ผ ์ฑ ์ ์์น (Single Responsibility Principle)
O: ๊ฐ๋ฐฉ-ํ์ ์์น (Open-Closed Principle)
L: ๋ฆฌ์ค์ฝํ ์นํ ์์น (Liskov Substitution Principle)
I: ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (Interface Segregation Principle)
D: ์์กด ์ญ์ ์์น (Dependency Inversion Principle)
โ SOLID ์์น์ ๊ฐ๋ฐ ๊ณผ์ ์์ ๋ฌธ์ ๋ฅผ ์๋ฐฉํ๊ณ , ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๋ฉฐ ์ ์ง๋ณด์๋ฅผ ์ฉ์ดํ๊ฒ ํ๋ ๋ฐ ํฐ ๋์์ ์ค๋๋ค.
ํด๋์ค๋ ๋จ ํ๋์ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํ๋ค.
// Bad Example
class UserService {
void registerUser(User user) { ... }
void sendEmail(User user) { ... } // ์ญํ ์ด ์์
}
// Good Example
class UserService {
void registerUser(User user) { ... }
}
class EmailService {
void sendEmail(User user) { ... }
}
ํ์ฅ์๋ ์ด๋ ค ์์ด์ผ ํ๊ณ , ๋ณ๊ฒฝ์๋ ๋ซํ ์์ด์ผ ํ๋ค.
interface DiscountPolicy {
int discount(int price);
}
class FixDiscountPolicy implements DiscountPolicy {
public int discount(int price) {
return price - 1000;
}
}
class OrderService {
private DiscountPolicy discountPolicy;
public OrderService(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
public void order(int price) {
int finalPrice = discountPolicy.discount(price);
// ์ฃผ๋ฌธ ์ฒ๋ฆฌ ๋ก์ง
}
}
ํ์ ํด๋์ค๋ ์์ ํด๋์ค์ ํ์๋ฅผ ๋์ฒดํ ์ ์์ด์ผ ํ๋ค.
class Bird {
void fly() {}
}
class Ostrich extends Bird {
@Override
void fly() {
throw new UnsupportedOperationException(); // ๋ ์ ์์
}
}
ํด๋ผ์ด์ธํธ๋ ์์ ์ด ์ฌ์ฉํ์ง ์๋ ์ธํฐํ์ด์ค์ ์์กดํ์ง ์์์ผ ํ๋ค.
// Bad Interface
interface Machine {
void print();
void scan();
void fax();
}
// Good Interfaces
interface Printer {
void print();
}
interface Scanner {
void scan();
}
๊ณ ์์ค ๋ชจ๋์ ์ ์์ค ๋ชจ๋์ ์์กดํ๋ฉด ์ ๋๋ฉฐ, ๋ ๋ค ์ถ์ํ์ ์์กดํด์ผ ํ๋ค.
// ๋์ ์
class MySQLDatabase {
void connect() { ... }
}
class UserService {
private MySQLDatabase db = new MySQLDatabase(); // ์ง์ ์์กด
}
// ์ข์ ์
interface Database {
void connect();
}
class MySQLDatabase implements Database {
public void connect() { ... }
}
class UserService {
private Database db;
public UserService(Database db) {
this.db = db;
}
}