Programming/Programming Study

[Programming Study] SOLID

hyunjuntyler 2023. 6. 25. 14:43

컴퓨터 프로그래밍에서 SOLID란 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙이다.

객체 지향에 대해서

모두가 알겠지만 객체 지향은 "누가 어떤 일을 할 것인가?" 가 핵심이다. 각자의 객체를 찾아내고 그것에 대한 역할을 정의하고 사용하는 것이 객체 지향 프로그래밍이라고 할 수 있다.

객체(object)?

객체는 속성(데이터)동작(메서드)을 가진 것을 이야기 한다. 보통 클래스를 이야기하며, 예를 들면 '사람' 이라는 클래스는 '눈', '코', '입', '팔', '다리' 와 같은 속성이 있는 것이고, '걷기', '먹기', '말하기' 같은 동작을 가진 객체라고 볼 수 있다.

SOLID

이제 본격적으로 SOLID에 대해서 공부해보자. SOLIDSRP, OCP, LSP, ISP, DIP의 약자로 이것들 또한 약자이다. 아주 용어자체도 코딩처럼 해놨다고 할 수 있겠다. SOLID는 소프트웨어의 개발 원칙이며, 소프트웨어의 설계와 구조를 개선하고 유지보수성, 재사용성, 확장성을 향상할 수 있다. 하나하나 알아보자!

1. SRP (Single Responsibility Principle : 단일 책임 원칙)

객체는 단 하나의 책임을 가져야 한다. 즉, 한 클래스는 변경의 이유가 하나여야 한다. 변경 사항이 발생했을 때 해당 책임을 지고있는 객체만 수정하면 된다. 그리고 이것은 본인이 책임지고 있는 부분 이외에는 영향을 주지 않는다.

2. OCP (Open-Closed Principle : 개방-폐쇄 원칙)

확장에는 열려 있어야 하고, 변경에는 닫혀있어야 한다. 즉 기존의 코드를 수정하지 않고, 새로운 기능을 추가할 수 있도록 확장 가능한 구조로 설계해야 한다.

3. LSP (Liskov Substitution Principle : 리스코프 치환 원칙)

리스코프 치환 원칙은 1988년 바바라 리스코프(Barbara Liskov)가 올바른 상속 관계의 특징을 정의하기 위해 발표한 것이다. 상위 타입을 사용하는 코드는 상위 타입 대신에 하위 타입을 대체하여 사용해도 문제가 없어야 한다. 상위타입이란 좀 더 일반적인 기능과 속성을 가진 객체를 의미하고, 하위 타입은 상위 타입을 상속받아 추가적인 기능을 확장한 클래스를 의미한다.

여기서 다형성(Polymorphism)의 원리가 등장한다. 다형성의 원리란, 여러개의 클래스가 동일한 메서드(동작)을 호출해도 다양한 동작을 수행할 수 있어야 한다. 코드로 예시를 들어보면 아래와 같다. Animal이라는 클래스는 상위타입이고 Dog, Cat은 하위타입이다.

class Animal {
    func makeSound() {
        print("Animal sound")
    }
}

class Cat: Animal {
    override func makeSound() {
        print("Meow!")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("Woof!")
    }
}

func makeAnimalSound(animal: Animal) {
    animal.makeSound()
}

let cat = Cat()
makeAnimalSound(animal: cat) // "Meow!" 출력

그리고 makeSound() 를 사용하면 CatDog 는 같은 메서드에 다른 결과가 나온다! 또한 makeAnimalSound 에서는 AnimalCat 둘다 사용가능하다.

4. ISP (Interface Segregation Principle : 인터페이스 분리 원칙)

자신이 사용하지 않는 기능에 의존하면 안 된다. 불필요한 의존성이 있으면 안 된다. 작은 인터페이스로 해당 기능에 집중하는 것이 좋다. 이 원칙은 단일 책임 원칙(SRP)과 비슷한 면이 있다. 예를 들면 자동차에서 주행기능과 멀티미디어기능이 인터페이스 적으로 분리되어야 하듯이 말이다. 물론 연결되는 상황은 두 기능을 같이 구현해 주면 된다.

5. DIP (Dependency Inversion Principle : 의존성 역전 원칙)

상위모듈이 하위모듈에 영향을 받으면 안된다. 둘 다 추상화에 의존해야 한다로 볼 수 있을 것 같다. 보통은 상위 모듈이 하위 모듈에 영향을 받는다. 예를 들면, '전화' 라는 상위 모듈이 '아이폰으로 통화하기', '갤럭시로 통화하기' 에 의존하면 안 되고, '핸드폰으로 통화하기' 에 의존해야 한다는 것이다!


이렇게 SOLID를 정리하면서 느낀 것은 이것들이 SwiftUI에서 어떻게 녹일 수 있을까? 하는 생각이 들었다. 조금 더 많이 부딪혀보면서 느껴봐야겠다.