Single Responsibility Principle
학생정보를 가지고, 데이터 저장 둘다 함
// 잘못된 예시: Student 클래스가 너무 많은 책임을 가짐
class Student(val name: String, val age: Int) {
fun saveToFile() {
// 파일 저장 로직
}
}
학생정보관리, 정보저장 따로함
// 올바른 예시: 단일 책임으로 클래스 분리
class Student(val name: String, val age: Int)
class StudentFileSaver {
fun save(student: Student) {
// 파일 저장 로직
}
}
Open/Closed Principle
결제방식을 추가할때마다 수정이 필요함
class PaymentProcessor {
fun processPayment(paymentType: String) {
when (paymentType) {
"CreditCard" -> println("Processing credit card payment")
"PayPal" -> println("Processing PayPal payment")
}
}
}
interface로 결제 방식 확장
기존 PaymentProcessor를 수정하지 않고, 새로운 결제 클래스만 추가
// 올바른 예시: 인터페이스로 결제 방식 확장
interface PaymentMethod {
fun processPayment()
}
class CreditCardPayment : PaymentMethod {
override fun processPayment() {
println("Processing credit card payment")
}
}
class PayPalPayment : PaymentMethod {
override fun processPayment() {
println("Processing PayPal payment")
}
}
class PaymentProcessor {
fun processPayment(paymentMethod: PaymentMethod) {
paymentMethod.processPayment()
}
}
Liskov Substitution Principle
펭귄 날수 없음
open class Bird {
open fun fly() {
println("Bird is flying")
}
}
class Penguin : Bird() {
override fun fly() {
throw UnsupportedOperationException("Penguins can't fly")
}
}
날 수 있는 새와 날 수 없는 새를 구분
open class Bird {
// 일반적인 새의 속성
}
interface Flyable {
fun fly()
}
class Eagle : Bird(), Flyable {
override fun fly() {
println("Eagle is flying")
}
}
class Penguin : Bird() {
// 날지 않음
}
Interface Segregation Principle
이를 사용하지 않는 클래스도 불필요한 메서드를 구현
// 잘못된 예시: 너무 많은 책임을 가진 Printer 인터페이스
interface Printer {
fun print()
fun scan()
fun fax()
}
class SimplePrinter : Printer {
override fun print() {
println("Printing...")
}
override fun scan() {
// 구현할 필요 없는 메서드
}
override fun fax() {
// 구현할 필요 없는 메서드
}
}
// 올바른 예시: 기능별로 인터페이스 분리
interface Printer {
fun print()
}
interface Scanner {
fun scan()
}
interface Fax {
fun fax()
}
class SimplePrinter : Printer {
override fun print() {
println("Printing...")
}
} Dependency Inversion Principle
Keyboard와 Monitor 클래스가 Computer 클래스에 의존
Computer가 Keyboard와 Monitor의 구체적인 구현에 의존하기 때문에 각종 변경 사항이 발생하면 Computer클래스도 같이 수정해야함
class Keyboard {
fun type() {
println("Typing on keyboard")
}
}
class Monitor {
fun display() {
println("Displaying on monitor")
}
}
class Computer {
private val keyboard = Keyboard()
private val monitor = Monitor()
fun run() {
keyboard.type()
monitor.display()
}
}
Computer 클래스는 InputDevice와 DisplayDevice라는 인터페이스에 의존
체적인 하위 클래스가 변경되더라도 영향을 받지 않게된다
interface InputDevice {
fun type()
}
interface DisplayDevice {
fun display()
}
class Keyboard : InputDevice {
override fun type() {
println("Typing on keyboard")
}
}
class Monitor : DisplayDevice {
override fun display() {
println("Displaying on monitor")
}
}
class Computer(private val inputDevice: InputDevice, private val displayDevice: DisplayDevice) {
fun run() {
inputDevice.type()
displayDevice.display()
}
}