SOLID 원칙 예시로 설명하기
1. SRP (단일 책임 원칙)
하나의 클래스는 하나의 변경 이유만 가져야 합니다. 클래스는 하나의 책임만을 가져야 합니다.
예시:
class 슈퍼히어로 {
constructor(이름, 능력) {
this.이름 = 이름;
this.능력 = 능력;
}
}
class 슈퍼히어로데이터베이스 {
슈퍼히어로_저장(슈퍼히어로) {
// 슈퍼히어로 데이터를 데이터베이스에 저장
}
슈퍼히어로_가져오기(이름) {
// 데이터베이스에서 슈퍼히어로 데이터 가져오기
}
}
2. OCP (개방-폐쇄 원칙)
소프트웨어 구성 요소는 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 합니다. 기능을 추가할 때 기존 코드를 변경하지 않아도 됩니다.
예시:
class 슈퍼히어로능력 {
활성화(슈퍼히어로) {
// 슈퍼히어로 능력 활성화
}
}
class 날기능력 extends 슈퍼히어로능력 {
활성화(슈퍼히어로) {
console.log(`${슈퍼히어로.이름}이(가) 날아갑니다!`);
}
}
class 슈퍼히어로 {
constructor(이름, 능력, 능력객체) {
this.이름 = 이름;
this.능력 = 능력;
this.능력객체 = 능력객체;
}
능력활성화() {
this.능력객체.활성화(this);
}
}
const 아이언맨 = new 슈퍼히어로("아이언맨", "기술", new 날기능력());
아이언맨.능력활성화(); // 출력: "아이언맨이(가) 날아갑니다!"
3. LSP (리스코프 치환 원칙)
하위 타입은 기본 타입의 역할을 대체하여 프로그램의 정확성을 해치지 않아야 합니다.
예시:
class 동물 {
날다() {
// 동물이 날 수 있는 로직
}
}
class 펭귄 extends 동물 {
날다() {
throw new Error("펭귄은 날지 못해요!");
}
}
function 새로운_새로_날게_하기(새) {
새.날다();
}
const 펭귄 = new 펭귄();
새로운_새로_날게_하기(펭귄); // 예외 발생하지만 프로그램은 정상 작동
4. ISP (인터페이스 분리 원칙)
클라이언트를 위한 여러 개의 인터페이스를 구성하는 것이 좋습니다. 클라이언트가 필요로 하는 인터페이스로 분리함으로써 불필요한 의존성을 피하고 변경에 유연하게 대처할 수 있습니다.
예시:
class 동물 {
// 동물의 공통 메서드
}
class 강아지 extends 동물 {
// 강아지에 관련된 메서드
}
class 고양이 extends 동물 {
// 고양이에 관련된 메서드
}
function 동물_케어(동물) {
// 동물의 케어 로직
}
5. DIP (의존관계 역전 원칙)
고수준 모듈은 저수준 모듈의 구현에 의존해서는 안됩니다. 추상화에 의존해야 합니다. 이는 코드의 유연성과 재사용성을 높여줍니다.
예시:
class 전원제어기 {
constructor(전원장치) {
this.전원장치 = 전원장치;
}
전원켜기() {
this.전원장치.전원켜기();
}
전원끄기() {
this.전원장치.전원끄기();
}
}
class 컴퓨터 {
전원켜기() {
// 컴퓨터 전원 켜는 로직
}
전원끄기() {
// 컴퓨터 전원 끄는 로직
}
}
class 에어컨 {
전원켜기() {
// 에어컨 전원 켜는 로직
}
전원끄기() {
// 에어컨 전원 끄는 로직
}
}
const 컴퓨터전원 = new 전원제어기(new 컴퓨터());
컴퓨터전원.전원켜기();