[JAVA] μ€νλ§κ³Ό κ°μ²΄μ§ν₯
- -
π’ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ΄λ ?
κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ μ»΄ν¨ν° νλ‘κ·Έλ¨μ λͺ λ Ήμ΄μ λͺ©λ‘μΌλ‘ 보λ μκ°μμ λ²μ΄λ μ¬λ¬ κ°μ λ 립λ λ¨μ, μ¦ "κ°μ²΄" λ€μ λͺ¨μμΌλ‘ νμ νκ³ μ νλ κ²μ΄λ€. κ°κ°μ κ°μ²΄λ λ©μΈμ§λ₯Ό μ£Όκ³ λ°κ³ , λ°μ΄ν°λ₯Ό μ²λ¦¬ν μ μλ€. (νλ ₯)
κ°μ²΄μ§ν₯ νλ‘κ·Έλλ°μ νλ‘κ·Έλ¨μ μ μ°νκ³ λ³κ²½μ΄ μ©μ΄νκ² λ§λ€κΈ° λλ¬Έμ λκ·λͺ¨ μννΈμ¨μ΄μ κ°λ°μ λ§μ΄ μ¬μ©λλ€.
νλ‘κ·Έλ¨μ μ€κ³ν λ, μλ° μΈμ΄μ λ€νμ±μ νμ©νμ¬ μν κ³Ό ꡬνμ λͺ νν λΆλ¦¬ν΄μΌ νλ€.
μν = μΈν°νμ΄μ€
ꡬν = μΈν°νμ΄μ€λ₯Ό ꡬνν ν΄λμ€, ꡬν κ°μ²΄
κ°μ²΄ μ€κ³μ μν (μΈν°νμ΄μ€)λ₯Ό λ¨Όμ λΆμ¬νκ³ , κ·Έ μν μ μννλ ꡬν κ°μ²΄λ₯Ό λ§λ λ€.
λ€νμ±μ λ³Έμ§μ΄λ
μΈν°νμ΄μ€λ₯Ό ꡬνν κ°μ²΄ μΈμ€ν΄μ€λ₯Ό μ€ν μμ μ μ μ°νκ² λ³κ²½ν μ μλ€. λ€νμ±μ λ³Έμ§μ μ΄ν΄νλ €λ©΄ νλ ₯μ΄λΌλ κ°μ²΄μ¬μ΄μ κ΄κ³μμ μμν΄μΌ νλ€. ν΄λΌμ΄μΈνΈλ₯Ό λ³κ²½νμ§ μκ³ , μλ²μ ꡬν κΈ°λ₯μ μ μ°νκ² λ³κ²½ν μ μλ€.
μ¦, μΈν°νμ΄μ€λ₯Ό μμ μ μΌλ‘ μ μ€κ³νλ κ²μ΄ μ€μνλ€.
μ€νλ§κ³Ό κ°μ²΄μ§ν₯
λ€νμ±μ΄ μ μΌ μ€μνκ³ , μ€νλ§μ μ΄ λ€νμ±μ κ·Ήλνν΄μ μ΄μ©ν μ μκ² λμμ€λ€. μ€νλ§μμ μ΄μΌκΈ°νλ μ μ΄μ μμ (IoC), μμ‘΄κ΄κ³ μ£Όμ (DI)μ λ€νμ±μ νμ©ν΄μ μν κ³Ό ꡬνμ νΈλ¦¬νκ² λ€λ£° μ μλλ‘ μ§μνλ€.
π‘ κ°μ²΄μ§ν₯μ 5μμΉ, SOLID
- λ¨μΌ μ± μ μμΉ (Single Responsibility principle)
- κ°λ°© νμ μμΉ (Open Closed Principle)
- 리μ€μ½ν μΉν μμΉ (Liscov Substitution Principle)
- μΈν°νμ΄μ€ λΆλ¦¬ μμΉ (Interface Sergregation Principle)
- μμ‘΄μ± μμ μμΉ (Dependency Inversion Principle)
1. SRP, λ¨μΌ μ± μ μμΉ
ν ν΄λμ€λ νλμ μ± μλ§ κ°μ ΈμΌ νλ€. νλμ μ± μμ΄λΌλ κ²μ ν΄ μλ μμ μλ μκ³ , λ¬Έλ§₯κ³Ό μν©μ λ°λΌ λ€λ₯΄κΈ° λλ¬Έμ λͺ¨νΈνλ€.
μ€μν κΈ°μ€μ λ³κ²½μ΄λ€. λ³κ²½μ΄ μμ λ νκΈ ν¨κ³Όκ° μ μΌλ©΄ λ¨μΌ μ± μ μμΉμ μ λ°λ₯Έ κ²μ΄λΌλ λ§μ΄λ€. (UI λ³κ²½, κ°μ²΄μ μμ±κ³Ό μ¬μ©μ λΆλ¦¬)
// μ¬μ©μμ μ 보λ₯Ό μ·¨κΈνλ ν΄λμ€
class User {
private String name;
private String email;
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
// λ°μ΄ν°λ² μ΄μ€ κ΄λ ¨ λ‘μ§μ μ²λ¦¬νλ ν΄λμ€
class UserRepository {
public void saveUser(User user) {
// μ¬κΈ°μ λ°μ΄ν°λ² μ΄μ€ μ μ₯ λ‘μ§ κ΅¬ν
}
}
μμ μ½λλ₯Ό μμλ‘, μ¬μ©μ μ 보λ₯Ό κ΄λ¦¬νλ ν΄λμ€μ μ¬μ©μμ λ°μ΄ν°λ₯Ό λ°μ΄ν°λ² μ΄μ€μ μ μ₯νλ λ‘μ§μ λΆλ¦¬ν μ μλ€.
2. OCP, κ°λ°© νμ μμΉ
μννΈμ¨μ΄ μμλ νμ₯μλ μ΄λ € μμΌλ λ³κ²½μλ λ«ν μμ΄μΌ νλ€. μΈν°νμ΄μ€λ₯Ό ꡬνν μλ‘μ΄ ν΄λμ€λ₯Ό νλ λ§λ€μ΄μ μλ‘μ΄ κΈ°λ₯μ ꡬν, λ€νμ±μ νμ©μ΄ κ°λ₯νλ€. κΈ°μ‘΄μ μ½λλ₯Ό λ³κ²½νμ§ μκ³ λ, ν΄λμ€μ κΈ°λ₯μ νμ₯ν μ μμ΄μΌ νλ€.
μ¦, μΈν°νμ΄μ€λ₯Ό ꡬνν μλ‘μ΄ ν΄λμ€λ₯Ό νλ λ§λ€μ΄μ μλ‘μ΄ κΈ°λ₯μ ꡬνν μ μμ΄μΌ νλ€. νμ§λ§ μ΄λ¬ν κ²½μ°μ ν΄λΌμ΄μΈνΈ, μ¦ μ½λλ₯Ό μμ ν΄μΌ νλ λ¬Έμ μ μ΄ μμ§λ§ κΉμ λ΄μ©μ΄κΈ°μ λ€μμ μΆκ°λ‘ μ€λͺ νκΈ°λ‘ νλ€!
abstract class Shape {
abstract double calculateArea();
}
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
}
class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
μ¬κΈ°μ 'Discount' ν΄λμ€λ μΆμ ν΄λμ€λ‘, λ€μν ν μΈμ¨μ μ μ©ν μ μλλ‘ νμ₯μ΄ κ°λ₯νλ κΈ°μ‘΄ ν μΈ κ³μ° λ‘μ§μ λ³κ²½ν νμκ° μλ€. μλ‘μ΄ ν μΈμ¨μ μΆκ°νκ³ μΆμ λλ 'Discount' λ₯Ό μμλ°λ μλ‘μ΄ ν΄λμ€λ₯Ό λ§λ€κΈ°λ§ νλ©΄ λλ€.
3. LSP, 리μ€μ½ν μΉν μμΉ
νλ‘κ·Έλ¨ κ°μ²΄λ νλ‘κ·Έλ¨μ μ νμ±μ κΉ¨λ¨λ¦¬μ§ μμΌλ©΄μ νμ νμ μ μΈμ€ν΄μ€λ‘ λ°κΏ μ μμ΄μΌ νλ€. μ¦, λΆλͺ¨ ν΄λμ€μ μΈμ€ν΄μ€ λμ μμ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μ¬μ©ν μ μμ΄μΌ νλ€λ μλ―Έμ΄λ€. λ€νμ±μμ νμ ν΄λμ€λ μΈν°νμ΄μ€ κ·μ½μ λ€ μ§μΌμΌ νλ€λ κ², λ€νμ±μ μ§μνκΈ° μν μμΉ, μΈν°νμ΄μ€λ₯Ό ꡬνν ꡬν체λ λ―Ώκ³ μ¬μ©νλ €λ©΄, μ΄ μμΉμ΄ νμνλ€.
ex) μλμ°¨ μΈν°νμ΄μ€μ μμ μ μμΌλ‘ κ°λΌλ κΈ°λ₯, λ€λ‘ κ°κ² ꡬννλ©΄ LSP μλ°, λ리λλΌλ μμΌλ‘ κ°μΌ νλ€.
class Bird {
public void fly() {
System.out.println("This bird can fly.");
}
}
class Duck extends Bird {
@Override
public void fly() {
System.out.println("Duck flies lower.");
}
}
class Ostrich extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("Ostrich cannot fly.");
}
}
μμ μμμμ Bird ν΄λμ€λ fly() λ©μλλ₯Ό κ°μ§κ³ μκ³ , Duckμ μ΄ λ©μλλ₯Ό μ€λ²λΌμ΄λνμ¬ λ€λ₯΄κ² ꡬννλ€. νμ§λ§, Ostrich ν΄λμ€λ fly() λ©μλλ₯Ό μ§μνμ§ μλλ€. μ΄ κ²½μ° λ¦¬μ€μ½ν μΉν μμΉμ μλ°°λλ€. μλνλ©΄ Bird νμ μ κ°μ²΄λ₯Ό Ostrich κ°μ²΄λ‘ λ체νμ λ, νλ‘κ·Έλ¨μ΄ μ€ν¨νκ² λκΈ° λλ¬Έμ΄λ€.
μμΉμ λ§κ² μμ λ μ½λ
class Bird {
}
class FlyingBird extends Bird {
public void fly() {
System.out.println("This bird can fly.");
}
}
class Duck extends FlyingBird {
@Override
public void fly() {
System.out.println("Duck flies lower.");
}
}
class Ostrich extends Bird {
// Ostrich ν΄λμ€λ FlyingBirdλ₯Ό μμλ°μ§ μμ
}
μ μμ λ μμμμ, λΉν κ°λ₯ν μλ€μ μν λ³λμ ν΄λμ€ FlyingBirdκ° λμ λμλ€. μ΄λ‘μ¨, Ostrichλ λΉνμ ꡬννλ ν΄λμ€λ₯Ό μμλ°μ§ μμΌλ―λ‘, Bird νμ μ κ°μ²΄λ₯Ό Ostrich κ°μ²΄λ‘ λ체νλ μν©μμ λΉν κΈ°λ₯μ νΈμΆν μΌμ΄ μμ΄μ§λ©° 리μ€μ½ν μΉν μμΉμ μ€μνκ² λλ€.
4. ISP, μΈν°νμ΄μ€ λΆλ¦¬ μμΉ
νΉμ ν΄λΌμ΄μΈνΈλ₯Ό μν μΈν°νμ΄μ€ μ¬λ¬ κ°κ° λ²μ© μΈν°νμ΄μ€ νλλ³΄λ€ λ«λ€. μλ₯Ό λ€μ΄ μλμ°¨ μΈν°νμ΄μ€λ₯Ό μ΄μ & μ λΉ μΈν°νμ΄μ€λ‘ λΆλ¦¬νκ³ μ¬μ©μ ν΄λΌμ΄μΈνΈλ₯Ό μ΄μ μ & μ λΉμ¬ ν΄λΌμ΄μΈνΈλ‘ λΆλ¦¬νλ€. λΆλ¦¬νλ©΄ μ λΉ μΈν°νμ΄μ€ μμ²΄κ° λ³κ²½λλ μ΄μ μ ν΄λΌμ΄μΈνΈμ μν₯μ μ£Όμ§ μλλ€. μΈν°νμ΄μ€κ° λͺ νν΄μ§κ³ , λ체 κ°λ₯μ±μ΄ λμμ§λ€.
interface Printer {
void printDocument(String document);
}
interface Scanner {
void scanDocument(String document);
}
class SimplePrinter implements Printer {
public void printDocument(String document) {
// Printing logic
}
}
class MultiFunctionMachine implements Printer, Scanner {
public void printDocument(String document) {
// Printing logic
}
public void scanDocument(String document) {
// Scanning logic
}
}
μ΄ μμμμ `SimplePrinter` λ μΈμ κΈ°λ₯λ§ νμλ‘ νκ³ , `MultiFunctionMachine`μ μΈμμ μ€μΊ κΈ°λ₯ λͺ¨λλ₯Ό νμλ‘ νλ€. κ°κ°μ ν΄λμ€λ μμ μ΄ νμλ‘ νλ μΈν°νμ΄μ€λ§ ꡬννλ©΄ λλ€.
5. DIP, μμ‘΄κ΄κ³ μμ μμΉ
"μΆμνμ μμ‘΄ν΄μΌμ§, ꡬ체νμ μμ‘΄νλ©΄ μλλ€." μμ‘΄μ± μ£Όμ μ μ΄ μμΉμ λ°λ₯΄λ λ°©λ² μ€ νλλ€. μ¦, ν΄λΌμ΄μΈνΈ μ½λκ° κ΅¬ν ν΄λμ€μ λ°λΌλ³΄μ§ λ§κ³ (μμ‘΄νμ§ λ§κ³ ), μΈν°νμ΄μ€μ μμ‘΄νλΌλ μλ―Έμ΄λ€. μν μ μμ‘΄νκ² ν΄μΌ νλ€λ κ²κ³Ό κ°λ€. κ°μ²΄ μΈμλ ν΄λΌμ΄μΈνΈκ° μΈν°νμ΄μ€μ μμ‘΄ν΄μΌ μ μ°νκ² κ΅¬ν체λ₯Ό λ³κ²½ν μ μλ€. ꡬν체μ μμ‘΄νκ² λλ©΄ λ³κ²½μ΄ μ΄λ €μμ§λ€.
μΆκ°λ‘ νλμ μμλ₯Ό λ€μλ©΄ Member Service κ° MemberRepository Interface λ§ λ°λΌλ΄μΌ νλ©°, κ·Έ ꡬν체μ λν΄μλ λͺ°λΌμΌ νλ€λ μλ―Έμ΄λ€.
interface Storage {
void saveData(String data);
}
class DiskStorage implements Storage {
public void saveData(String data) {
// Save data to disk
}
}
class CloudStorage implements Storage {
public void saveData(String data) {
// Save data to cloud
}
}
class DataManager {
private Storage storage;
public DataManager(Storage storage) {
this.storage = storage;
}
public void save(String data) {
storage.saveData(data);
}
}
`DataManager` ν΄λμ€λ ꡬ체μ μΈ `Storage` ꡬν체μ μμ‘΄νμ§ μκ³ `Storage` μΈν°νμ΄μ€μ μμ‘΄νλ€. μ΄λ₯Ό ν΅ν΄ `DataManager`μ μ μ₯ λ©μ»€λμ¦μ λ³κ²½ν λ `DataManager` μ½λλ₯Ό λ³κ²½ν νμ μμ΄, λ€λ₯Έ `Storage` ꡬν체λ₯Ό μ£Όμ νκΈ°λ§ νλ©΄ λλ€.
*οΈβ£ μ 리
μ€νλ§μ λ€μ κΈ°μ λ‘ λ€νμ± + OCP & DIP λ₯Ό κ°λ₯νκ² μ§μνλ€.
DI (Dependency Injection) = μμ‘΄κ΄κ³, μμ‘΄μ± μ£Όμ
DI 컨ν
μ΄λ μ 곡
ν΄λΌμ΄μΈνΈ μ½λμ λ³κ²½ μμ΄ κΈ°λ₯ νμ₯
'Java' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[μ€νλ§ λΆνΈμ JPA νμ© 1] μ 리 (0) | 2023.11.13 |
---|---|
μ±κΈν€ ν¨ν΄μ΄λ (0) | 2023.10.25 |
컀λ₯μ ν(Connection Pool)μ΄λ (0) | 2023.07.31 |
Spring κ³Ό SpringBoot μ μ°¨μ΄μ (0) | 2023.07.31 |
HashMap (0) | 2022.10.20 |
μμ€ν κ³΅κ° κ°μ¬ν©λλ€