SOLID 원칙이란?
유지보수성, 유연한 확장성, 재사용성 같은 좋은 코드를 만들 수 있는 원칙이다.
코드는 한번 만들고 끝나는게 아니라 유지, 보수, 확장을 거쳐야하기 때문에 처음에 설계할 때 이에 유용한 코드를 만드는 것이 좋다.
목적: 결합도는 낮추고, 응집도는 높이자!
결합도: 모듈과 모듈간의 의존 정도 == 클래스간 관계가 느슨 -> 변경이 자유롭다.
응집도: 한 모듈 내 구성요소의 연관정도 == 클래스의 내부 목적이 뚜렷 -> 코드가 명확
예)
battle과제에서 player가 무기를 생성하고 관리하는 형태는 여러 책임이 혼합되어 응집도가 낮다.
그럼 player가 외부에서 무기를 공급받고, 공격만 하는 주체라면? => 결합도가 낮아진다.
interface Weapon{
void use();
}
class Sword implements Weapon{
public void use(){
System.out.println("칼로 베었다!");
}
}
class Gun implements Weapon{
public void use(){
System.out.println("총을 발사했다.");
}
}
class Player{
private Weapon weapon;
public Player(Weapon weapon){
this.weapon = weapon;
}
public void attack(){
weapon.use();
}
}
player는 attack()책임 하나에만 집중하기 때문에 응집도가 높아진다.
결과적으로, 무기를 교체하기 쉽다.
solid원칙 알아보기
S: 단일책임의 원칙
여러 책임을 가지면 한 책임의 변경이 다른 책임에 영향을 주기 때문에, 클래스는 단 하나의 책임에 집중하도록 한다.
- 코드의 명확성 상승
- 재사용성이 높아진다.
class ReportGenerator{
public void generateReport(); //보고서 생성
}
class EmailSender{
public void sendEmail();//이메일 전송
}
O: 개방 - 폐쇄의 법칙
확장에는 열려있고, 수정에는 닫혀 있다. => 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있다.
- 추상화 (인터페이스, 추상 클래스)에 의존한다.
- 구체적인 구현 클래스에 의존하지 않는다.
//결제수단 인터페이스
public interface PaymentMethod{
void pay();
}
//신용카드 결제
public class CreditCard implements PaymentMethod{
public void pay(){//신용카드 결제 로직}
}
//카카오페이
public class kakaoPay implements PaymentMethod{
public void pay(){//카카오페이 결제 로직}
}
//결제 처리기
public class PayMentProcessor {
public void process(PaymentMethod paymentmethod){
paymentmethod.pay() //어떤 결제 수단이 와도 코드는 동일
}
}
=> 확장이 편리하다 : 인터페이스에 의존을 함으로서, 새로운 결제수단이 생겨도 추가만 하면 되고, 기존 코드를 수정할 필요가 없어진다.
L: 리스코프 치환 법칙
하위 타입은 언제나 상위 타입으로 대체될 수 있어야한다. (업캐스팅)
상속은 is-A관계를 따른다.
interface Bird{
move();
}
class FlyingBird implements Bird{
pulbic void move() {System.out.println("날아요")};
}
class WalkingBird implements Bird{
public void move(){ System.out.println("걸어요")};
}
I: 인터페이스 분리 원칙
(ISP): 자신이 사용하지 않는 메서드에 의존하지 않는다.
클래스가 불필요한 메서드를 구현하지 않는다는 점에서 SRP와 관련있다.
=> 인터페이스 변경 시 영향받는 클래스를 최소화한다.
interface Workable{
void work();
}
interface Eatable{
void eat();
}
class Robot implements Wrokable{
public void work(){
//일 처리 로직
}
}
//로봇은 일만 하면 된다.
D: 의존성 역전 원칙
(DIP): 구체적인 하위 클래스에 의존하지 않고, 인터페이스나 추상 클래스에 의존한다 .
* 의존성의 방향을 역전 시켜 유연한 관계를 만든다.
의존=사용
추상화
interface Device{
void turnOn();
void turnOff();
}
//다양한 가전
class Light implements Device{//구현}
class AirConditioner implements Device{//구현}
class CoffeeMachine implements Device{//구현}
//스마트홈 스위치는 추상화에만 의존해서 device와 연결
public class SmartSwitch{
private final List<Device> devices;
public smartHomeSwirch(List<Device> devices){
this.devices=devices;
}
public void operateAll(String command){
for(Device device:devices)
if("on".equals(command) device turnOn();)
else device.turnOff();
}
}
//device면 다 받을 수 있다. Device 생성의 책임이 없고 외부에서 주입받는다
SOLID 원칙을 배움으로서 좋은 코드가 무엇인지 이해할 수 있었고,
유지보수성을 높이는 코드를 작성하는 생각의 틀을 가질 수 있었다.
또 현업에서는 solid원칙과 보기 편한 코드 등 여러 맥락을 파악해서 코드를 짠다는 점도 이해했다.
'자바' 카테고리의 다른 글
| week10: 자바 네트워크 (0) | 2025.11.09 |
|---|---|
| week9.java GUI_Swing, Event 실습 (0) | 2025.11.02 |
| week4: 자바 Thread -2 (0) | 2025.10.01 |
| week4: 자바 Thread (0) | 2025.09.27 |
| week3. 자바 Collections (set,list,map ) (0) | 2025.09.23 |