๐Ÿ”ฅTIL๐Ÿ”ฅ์ŠคํŒŒ๋ฅดํƒ€ | SOLID ์›์น™

hyihyiยท2024๋…„ 3์›” 19์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
64/70
post-thumbnail

S ๋‹จ์ผ ์ฑ…์ž„ ์›์น™ (Single Responsibility principle)
O ๊ฐœ๋ฐฉ ํ์‡„ ์›์น™ (Open Closed Principle)
L ๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›์น™ (Liscov Substitution Principle)
I ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™ (Interface Sergregation Principle)
D ์˜์กด์„ฑ ์—ญ์ „ ์›์น™ (Dependency Inversion Principle)

1. S ๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™

ํ•ด๋‹น ๋ชจ๋“ˆ์ด ์—ฌ๋Ÿฌ ๋Œ€์ƒ ๋˜๋Š” ์•กํ„ฐ๋“ค์— ๋Œ€ํ•ด ์ฑ…์ž„์„ ๊ฐ€์ ธ์„œ๋Š” ์•ˆ๋˜๊ณ , ์˜ค์ง ํ•˜๋‚˜์˜ ์•กํ„ฐ์— ๋Œ€ํ•ด์„œ๋งŒ ์ฑ…์ž„์„ ์ ธ์•ผ ํ•œ๋‹ค.
์ฆ‰, ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ์˜ค์ง ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค.

๐Ÿค”๊ทธ๋Ÿผ ํด๋ž˜์Šค๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์•„์ง€์ง€ ์•Š์„๊นŒ?
โžก ํด๋ž˜์Šค ํ•˜๋‚˜๊ฐ€ ๊ธด ๊ฒƒ๋ณด๋‹ค๋Š” ๋งŽ์€ ๊ฒŒ ๋‚ซ๋‹ค.

// ๋‚˜์œ ์˜ˆ
class UserSettings {
    fun changeUsername(user: User, newUsername: String) {
        // ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋กœ์ง
    }

    fun saveSettings(settings: Settings) {
        // ์„ค์ • ์ €์žฅ ๋กœ์ง
    }
}
-------------------------------------------------------------
// ์ข‹์€ ์˜ˆ
class User {
    fun changeUsername(newUsername: String) {
        // ์‚ฌ์šฉ์ž ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋กœ์ง
    }
}

class SettingsManager {
    fun saveSettings(settings: Settings) {
        // ์„ค์ • ์ €์žฅ ๋กœ์ง
    }
}

2. O ๊ฐœ๋ฐฉ ํ์‡„ ์›์น™

ํ™•์žฅ์— ๋Œ€ํ•ด์„œ๋Š” ์—ด๋ ค์žˆ๊ณ  ์ˆ˜์ •์—๋Š” ๋‹ซํ˜€์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™
ํ™•์žฅ์— ๋Œ€ํ•ด ์—ด๋ ค์žˆ๋‹ค : ์š”๊ตฌ์‚ฌํ•ญ์ด ๋ณ€๊ฒฝ๋  ๋•Œ ์ƒˆ๋กœ์šด ๋™์ž‘์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
์ˆ˜์ •์— ๋Œ€ํ•ด ๋‹ซํ˜€ ์žˆ๋‹ค : ๊ธฐ์กด์˜ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋™์ž‘์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

// ๋‚˜์œ ์˜ˆ
class Rectangle {
    var width: Double = 0.0
    var height: Double = 0.0
}

class AreaCalculator {
    fun calculateRectangleArea(rectangle: Rectangle): Double {
        return rectangle.width * rectangle.height
    }
}
-------------------------------------------------------------
// ์ข‹์€ ์˜ˆ
interface Shape {
    fun area(): Double
}

class Rectangle(private val width: Double, private val height: Double) : Shape {
    override fun area() = width * height
}

class Circle(private val radius: Double) : Shape {
    override fun area() = Math.PI * radius * radius
}

class AreaCalculator {
    fun calculateArea(shape: Shape): Double {
        return shape.area()
    }
}

3. L ๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›์น™

๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ž์‹ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™
ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๋Š” ์ƒ์œ„ ํƒ€์ž…์ด ํ•˜์œ„ ํƒ€์ž…์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์ฐจ์ด์ ์„ ์ธ์‹ํ•˜์ง€ ๋ชปํ•œ ์ฑ„ ์ƒ์œ„ ํƒ€์ž…์˜ ํผ๋ธ”๋ฆญ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

// ๋‚˜์œ ์˜ˆ
open class Bird {
    open fun fly() {}
}

class Duck : Bird()

class Ostrich : Bird() { 

// ํƒ€์กฐ๋Š” ๋‚  ์ˆ˜ ์—†์ง€๋งŒ Bird ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์— flay ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
    override fun fly() {
        throw UnsupportedOperationException("Cannot fly")
    }
}
-------------------------------------------------------------
// ์ข‹์€ ์˜ˆ
interface FlyingBird {
    fun fly()
}

interface NonFlyingBird {}

class Duck : FlyingBird {
    override fun fly() {
        // ๊ตฌํ˜„
    }
}

class Ostrich : NonFlyingBird {
    // ๋น„ํ–‰ํ•˜์ง€ ์•Š๋Š” ์ƒˆ ๊ด€๋ จ ๊ตฌํ˜„
}

-> ๋‚  ์ˆ˜ ์—†๋Š” ์ƒˆ๋ผ๋„ Bird ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉด fly ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.
๊ทธ๋ž˜์„œ ๋‚  ์ˆ˜ ์žˆ๋Š” ์ƒˆ์™€ ๋‚ ์ง€ ๋ชปํ•˜๋Š” ์ƒˆ๊ฐ€ ๋‹ค๋ฅธ ๋™์ž‘์„ ํ•˜๋„๋ก ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ๋ถ„ํ–ˆ๋‹ค.

4. I ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™

๊ฐ์ฒด๋Š” ์ž์‹ ์ด ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๋ฉ”์†Œ๋“œ์— ์˜์กดํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค๋Š” ์›์น™
๋ฌด์˜๋ฏธํ•œ ๋ฉ”์†Œ๋“œ์˜ ๊ตฌํ˜„์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•œ ๋ฉ”์†Œ๋“œ๋งŒ์„ ์ƒ์†/๊ตฌํ˜„ํ•˜๋„๋ก ๊ถŒ๊ณ ํ•œ๋‹ค.

// ๋‚˜์œ ์˜ˆ
interface Worker {
    fun work()
    fun eat()
}

class HumanWorker : Worker {
    override fun work() {
        // ์ž‘์—…
    }

    override fun eat() {
        // ์‹์‚ฌ
    }
}
-------------------------------------------------------------
// ์ข‹์€ ์˜ˆ
interface Workable {
    fun work()
}

interface Eatable {
    fun eat()
}

class HumanWorker : Workable, Eatable {
    override fun work() {
        // ์ž‘์—…
    }

    override fun eat() {
        // ์‹์‚ฌ
    }
}

work, eat ๋ฉ”์„œ๋“œ๋ฅผ Worker ์ธํ„ฐํŽ˜์ด์Šค์— ํ•œ๊บผ๋ฒˆ์— ๋„ฃ์–ด๋ฒ„๋ฆฌ๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋งŒ ์“ฐ๊ณ  ์‹ถ๋”๋ผ๋„ ๋ชจ๋‘ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

5. D ์˜์กด ์—ญ์ „ ์›์น™

์ €์ˆ˜์ค€ ๋ชจ๋“ˆ์ด ๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค๋Š” ์›์น™
๊ณ ์ˆ˜์ค€ ๋ชจ๋“ˆ : ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์ด๋‚˜ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํด๋ž˜์Šค
์ €์ˆ˜์ค€ ๋ชจ๋“ˆ : ์ด๋Ÿฌํ•œ ๋กœ์ง์„ ์‹คํ–‰ํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์„ธ๋ถ€์ ์ธ ๊ตฌํ˜„(๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ, I/O ์ž‘์—… ๋“ฑ)์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค

// ๋‚˜์œ ์˜ˆ
class LightBulb {
    fun turnOn() {}
    fun turnOff() {}
}

class Switch(val bulb: LightBulb) {
    fun operate() {
        bulb.turnOn()
        bulb.turnOff()
    }
}
-------------------------------------------------------------
// ์ข‹์€ ์˜ˆ
interface Switchable {
    fun turnOn()
    fun turnOff()
}

class LightBulb : Switchable {
    override fun turnOn() {}
    override fun turnOff() {}
}

class Switch(val device: Switchable) {
    fun operate() {
        device.turnOn()
        device.turnOff()
    }
}

๐ŸŒ€์ด๋Ÿฐ ์›์น™๋“ค์„ ๋‹ค ์ง€์ผœ์•ผ ํ•œ๋‹ค๋Š” ๊ฑด๊ฐ€ / ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋ช‡๊ฐœ์”ฉ๋งŒ ์ง€ํ‚ค๋ฉด ๋œ๋‹ค๋Š” ๊ฑด๊ฐ€?

โžก SOLID ์›์น™์„ ์ตœ๋Œ€ํ•œ ์ง€์ผœ์•ผ ํ•œ๋‹ค.

๊ฐ ํŒ€์—์„œ ์ฝ”๋“œ ์งœ๋Š” ๋ฐฉ์‹์„ ๋ดค์„ ๋•Œ ์›์น™์„ ์ง€์ผฐ์œผ๋ฉด ๋ฌด์กฐ๊ฑด ์ง€์ผœ์•ผ ํ•˜๋Š” ๊ฒŒ ๋งž๊ณ  ์•„๋‹ˆ๋ผ๋ฉด ํ—๋ ํ•˜๊ตฌ๋‚˜ ์ƒ๊ฐํ•˜์ž!

profile
๋‚ด๊ฐ€ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์“ฐ๋Š” ๋ธ”๋กœ๊ทธ

0๊ฐœ์˜ ๋Œ“๊ธ€