-
단일 책임 원칙(Single Responsibility Principle)기록/OOP 2023. 1. 28. 15:31
SOLID의 단일 책임 원칙(Single responsibility principle)은 클래스나 모듈(이하 클래스로 통일해서 작성)은 하나의 책임만을 가지며, 그 책임을 완전히 캡슐화해야 함을 말합니다. 캡슐화란, 변수와 함수를 하나의 단위로 묶는 것을 말합니다. 이는 대체로 클래스를 통해 구현합니다.
다음의 Music struct를 가지고 재생하는 MusicPlayer class를 예시로 들어보겠습니다.
struct Music { let name: String let artist: String let length: TimeInterval }
다음은 단일 책임 원칙을 위배한 코드입니다.
class MusicPlayer { private var musics: [Music] private var currentMusicIndex = 0 init(_ musics: [Music]) { self.musics = musics } func play() { } func playPreviousMusic() { } func playNextMusic() { } func paues() { } // 재생중인 노래 정보를 출력 func printCurrentMusic() { let currentMusic = musics[currentMusicIndex] print("이름: \(currentMusic.name) 아티스트: \(currentMusic.artist) 길이: \(currentMusic.length)") } } let musics: [Music] = [ .init(name: "High", artist: "The Chainsmokers", length: 175), .init(name: "Bones", artist: "Imagin Dragons", length: 165) ] let player = MusicPlayer(musics) player.printCurrentMusic()
MusicPlayer 클래스는 노래를 재생하는 책임과 노래의 정보를 출력하는 책임을 가지고 있습니다. 따라서 MusicPlayer는 두 가지 이유로 변경될 수 있습니다. 첫 번째로 노래를 재생하는 내용 때문에 변경될 수 있습니다. 이는 음악을 재생하는 클래스이므로 실질적인 변경입니다. 두 번째로는 출력 내용 때문에 변경될 수 있습니다. 직관적으로도 현재 재생되고 있는 노래의 정보를 직접 출력하는 printCurrentMusic() 함수는 MusicPlayer에 어울리지 않으며 이 때문에 변경된다는 것은 어색합니다. 이 문제는 하나의 클래스에서 여러 가지 책임을 가지고 있기 때문이며, 따라서 분리된 책임에 대해 클래스도 분리를 해줘야 합니다. 그렇게 하면 클래스에는 필요한 기능들만이 캡슐화되고 응집도도 높아지겠죠.
다음은 단일 책임 원칙을 준수하도록 수정한 코드입니다.
class MusicPlayer { private var musics: [Music] private var currentMusicIndex = 0 // 현재 재생중인 노래를 던져줌. var currentMusic: Music { musics[currentMusicIndex] } init(_ musics: [Music]) { self.musics = musics } func play() { } func playPreviousMusic() { } func playNextMusic() { } func paues() { } // func fetchCurrentMusic() -> Music { // musics[currentMusicIndex] // } } // 정보를 받아와서 원하는 형식으로 출력 func printMusicInformation(_ player: MusicPlayer) { let music = player.currentMusic print("이름: \(music.name) 아티스트: \(music.artist) 길이: \(music.length)") } let musics: [Music] = [ .init(name: "High", artist: "The Chainsmokers", length: 175), .init(name: "Bones", artist: "Imagin Dragons", length: 165) ] let player = MusicPlayer(musics) printMusicInformation(player)
'기록 > OOP' 카테고리의 다른 글
의존성 역전 원칙(Dependency Inversion Principle) (0) 2023.01.31 인터페이스 분리 원칙(Interface Segregation Principle) (0) 2023.01.31 리스코프 치환 원칙(Liscov Substitution Principle) (1) 2023.01.30 개방-폐쇄 원칙(Open-Closed Principle) (0) 2023.01.28