SOLID 원칙
소프트웨어 작업에서 코드를 리팩터링하여 읽기 쉽고 확장하기 쉽게 적용하는 지침
두문자 | 약어 | 개념 |
S | SRP | 단일 책임 원칙 (Single responsibility principle) : 한 클래스는 하나의 책임만 가진다. |
O | OCP | 개방/폐쇄 원칙 (Open/closed principle) : 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다. |
L | LSP | 리스코프 치환 원칙 (Liskov substitution principle) : 프로그램의 객체는 프로그램의 정확성을 깨지않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다. |
I | ISP | 인터페이스 분리 원칙 (Interface segregation principle) : 특정 클라이언트를 위한 인터페이스 여러개가 범용 인스턴스 하나보다 낫다. |
D | DIP | 의존관계 역전 원칙 (Dependency inversion principle) : 추상화에 의존해야지, 구체화에 의존하면 안된다. |
1. SRP, 단일책임 원칙 : 객체는 단 하나의 책임(순서)만 가진다
응집도는 높게, 결합도는 낮게, 캡슐화가 가장 잘 발현됨,
2. OCP, 개방폐쇄 원칙 : 기존 코드를 변경하지 않으면서 기능을 추가할 수 있도록
//d가 추가되면 else if가 추가되면서
//기존 코드를 수정해야함
function main(type){
if(type === 'a'){
doA();
}else if(type === 'b'){
doB();
}else if(type === 'c'){
doC();
}else if(type === 'd'){
doD();
}else{
error;
}
}
//d가 추가되어도 수정이 아닌 추가만으로 가능함
interface Doable {
do(): void;
}
function main(type: Doable){
type.do();
}
const a = {do(){}}
const b = {do(){}}
const c = {do(){}}
const d = {do(){}}
3. LSP, 리스코프치환 원칙 : 자식 클래스는 최소한 부모클래스에서 가능한 행위를 수행할 수 있어야 한다.
자식 클래스는 부모클래스를 대체할 수 있어야함
class Animal{
isAnimal(){
return true;
}
}
class Bird extends Animal{
fly(){
return '파닥파닥';
}
isBird(){
return true;
}
}
class Penguin extends Bird{
override fly(){
throw new Error('못날아');
//type:never return
//부모의 타입을 자식이 다르게 정의하면 위반됨
}
}
console.log(new Animal().isAnimal()); //true
console.log(new Penguin().fly().at(1)); //error
4. ISP, 인터페이스분리 원칙 : 자신이 사용하지 않는 인터페이스는 구현하지 말아야함 (인터페이스의 단일 원칙)
interface IBird{
fly(): string;
quack(): string;
//필요이상의 속성을 가져서 활용되지 못함
//분리할 필요가 있음
}
class Bird extends Animal implements IBird{
//IBird에 fly가 있어서 불필요하지만 구현해야하는 문제
fly(){
return '파닥파닥';
}
quack(){
return '짹짹';
}
isBird(){
return true;
}
}
class Penguin extends Bird{
fly(){
throw new Error('못날아')
}
}
//interface 메서드 분리해주기
interface Quackable{
quack(): string;
}
interface Flyable{
fly(): string;
}
class Bird extends Aninmal implents Quackable{
~~
}
///필요에 따라 다중 implements 가능
class Bird extends Aninmal implements Quackable, Flyable{
~~
}
5.DIP, 의존역전 원칙 : 추상성이 높은 클래스와 의존 관계를 맺어야 한다.
//강결합 상태
function main(){
a.do();
}
//약결합 권장
function main(grimpan: Grimpan){
grimpan.initialize();
}
main(Grimpan.getInstance())
main(IEGrimpan.getInstance())
main(ChromeGrimpan.getInstance())
//매개변수나 생성자로 외부 객체 받기
//외부객체의 타입은 interface, abstract class로 받기
interface IObj{}
class Obj implements IObj{}
class A{
constructor(obj?: IObj){}
setObj(obj: IObj){}
}
new A(new Obj()) //생성자 주입
new A().setObj(new Obj()) //setter 주입
반응형
'JS > [inflearn] TS JS 디자인패턴' 카테고리의 다른 글
생성 패턴 (Creational Pattern) _ 빌더(Builder) (0) | 2025.01.18 |
---|---|
생성 패턴 (Creational Pattern) _ 추상 팩토리(Abstract Factory) (0) | 2025.01.17 |
생성 패턴 (Creational Pattern) _ 팩토리 메서드(Factory Method) (0) | 2025.01.16 |
생성 패턴 (Creational Pattern) _ 싱글턴 (Singleton) (0) | 2025.01.16 |
디자인 패턴(Design Pattern)이란 (0) | 2025.01.13 |