Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
31 |
Tags
- &연산
- 문서번호
- TS
- Strict
- TypeScript
- es6
- 전역변수
- font-size
- npm
- 으
- 0.25px border
- 클론코딩
- 1px border
- 10px
- angular
- github
- 0.75px border
- 데이터베이스 #try #이중
- ZOOM
- 타입스크립트
- jwt
- 당근마켓
- 컴포넌튼
- Props
- entity
- literal
- Websocket
- ES5
- 0.5px border
- 서버리스 #
Archives
- Today
- Total
복잡한뇌구조마냥
[JAVA] 객체 지향 설계의 5대 원칙 – SOLID 본문
1. SOLID란?
SOLID는 로버트 C. 마틴(Robert C. Martin, Uncle Bob)이 정리한 객체 지향 설계 5대 원칙의 앞글자를 딴 용어입니다.
목표: 유지보수성, 확장성, 재사용성이 높은 코드 설계
약어 | 원칙 | 이름의미 |
S | SRP: 단일 책임 원칙 | 한 클래스는 하나의 책임만 가져야 한다 |
O | OCP: 개방-폐쇄 원칙 | 확장에는 열려 있고, 변경에는 닫혀 있어야 한다 |
L | LSP: 리스코프 치환 원칙 | 하위 타입은 상위 타입을 대체할 수 있어야 한다 |
I | ISP: 인터페이스 분리 원칙 | 사용하지 않는 메서드는 만들지 않는다 |
D | DIP: 의존 역전 원칙 | 추상화에 의존하고, 구체화에 의존하지 않는다 |
2. SRP – 단일 책임 원칙 (Single Responsibility Principle)
정의
한 클래스는 오직 하나의 변경 이유만 가져야 한다.
- 한 클래스가 여러 가지 역할을 하면, 한 부분의 변경이 다른 기능에 영향을 줄 수 있음.
- 책임이 분리되어야 수정 범위가 작아지고 유지보수가 쉬워짐.
위반 예시
public class ReportManager {
public void generateReport() { /* 보고서 생성 */ }
public void printReport() { /* 보고서 출력 */ }
}
- 보고서 생성과 출력이라는 두 책임이 하나의 클래스에 있음.
개선 예
public class ReportGenerator { public void generateReport() { /* ... */ } }
public class ReportPrinter { public void printReport() { /* ... */ } }
3. OCP – 개방-폐쇄 원칙 (Open-Closed Principle)
정의
확장에는 열려 있고, 변경에는 닫혀 있어야 한다.
- 새로운 기능을 추가할 때 기존 코드를 수정하지 않고 확장할 수 있어야 함.
위반 예시
public class DiscountService {
public double getDiscount(String type) {
if (type.equals("VIP")) return 0.2;
else if (type.equals("GOLD")) return 0.1;
else return 0.0;
}
}
- 새로운 할인 정책 추가 시 if-else 수정 필요.
개선 예시 (다형성 활용)
interface DiscountPolicy { double getDiscount(); }
class VipDiscount implements DiscountPolicy { public double getDiscount() { return 0.2; } }
class GoldDiscount implements DiscountPolicy { public double getDiscount() { return 0.1; } }
public class DiscountService {
public double apply(DiscountPolicy policy) { return policy.getDiscount(); }
}
4. LSP – 리스코프 치환 원칙 (Liskov Substitution Principle)
정의
하위 클래스는 상위 클래스의 행위를 변경하지 않고 대체 가능해야 한다.
- 부모 클래스 객체가 사용되는 곳에 자식 클래스를 넣어도 정상 동작해야 함.
- 계약(Contract) 위반 시 원칙 위반.
위반 예시
class Rectangle {
protected int width, height;
public void setWidth(int w) { this.width = w; }
public void setHeight(int h) { this.height = h; }
}
class Square extends Rectangle {
@Override
public void setWidth(int w) {
this.width = w; this.height = w; // 강제로 정사각형 유지
}
}
- Rectangle을 기대했는데 Square는 동작이 달라짐.
해결
- 상속 대신 구성(Composition) 활용
- 계약 위반 없이 공통 동작 재정의
5. ISP – 인터페이스 분리 원칙 (Interface Segregation Principle)
정의
클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야 한다.
- 너무 많은 메서드를 가진 “비대한” 인터페이스는 피해야 함.
위반 예시
interface Machine {
void print();
void scan();
void fax();
}
class SimplePrinter implements Machine {
public void print() { /* ok */ }
public void scan() { throw new UnsupportedOperationException(); }
public void fax() { throw new UnsupportedOperationException(); }
}
개선 예시
interface Printer { void print(); }
interface Scanner { void scan(); }
class SimplePrinter implements Printer { public void print() { /* ok */ } }
6. DIP – 의존 역전 원칙 (Dependency Inversion Principle)
정의
고수준 모듈은 저수준 모듈에 의존하지 않고, 추상화에 의존해야 한다.
- 구현 클래스가 아닌 인터페이스/추상 클래스에 의존
- 의존성 주입(DI) 패턴과 함께 사용
위반 예시
class MySQLRepository {
public void save() { /* MySQL 저장 */ }
}
class UserService {
private MySQLRepository repo = new MySQLRepository();
}
- UserService가 MySQL에 종속됨 → DB 변경 어려움.
개선 예시
interface UserRepository { void save(); }
class MySQLRepository implements UserRepository {
public void save() { /* MySQL 저장 */ }
}
class UserService {
private final UserRepository repo;
public UserService(UserRepository repo) { this.repo = repo; }
}
7. 마무리
SOLID 원칙은 코드 품질을 높이는 설계 지침입니다.
단, 원칙 준수에 집착하면 오히려 복잡성이 증가할 수 있으므로 필요한 곳에 적절히 적용하는 것이 중요합니다.
참고자료:
https://velog.io/@haero_kim/SOLID-%EC%9B%90%EC%B9%99-%EC%96%B4%EB%A0%B5%EC%A7%80-%EC%95%8A%EB%8B%A4
SOLID 원칙, 어렵지 않다!
객체지향 프로그래밍 설계 원칙에 대해 알아보기
velog.io
LIST
'BE > JAVA' 카테고리의 다른 글
[JAVA] Effective Java - 로 타입(raw type)은 사용하지 말라 (26) (2) | 2025.08.11 |
---|---|
[JAVA] Effective Java - 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (23) (5) | 2025.08.11 |
[JAVA] 서블릿(Servlet) (0) | 2025.08.08 |
[JAVA] JSP ( Java Server Pages ) (0) | 2025.08.07 |
[JAVA] Effective Java - clone 재정의는 주의해서 진행하라 (13) (4) | 2025.08.03 |