자바

week5: 자바 SOLID원칙

aerimi-code 2025. 10. 3. 21:37

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