Kotlin

클래스 조합

코드닭 2024. 4. 23. 18:54

조합 (composition) : has-a 관계

중복 로직을 갖는 객체를 구현, 이 객체를 주입받아 중복 로직을 호출하는 방법

(중복 로직 : 여러 객체나 클래스에서 반복적으로 사용되는 비슷한 코드 또는 동작)

여러 클래스에서 어떠한 로직이 반복된다면 그 로직을 처리하는 클래스를 만들고 그 클래스에게 그 로직을 위임

class Bag(          // 중복 로직을 갖는 객체 생성
    val maxWeight: Int,
    var currentWeight: Int = 0,
) {
    var itemList: MutableList<Item> = mutableListOf()

    fun takeItem(item: Item) {
        //  //객체(item)을 전달받아 자신의 로직으로 처리
    }
}

class Hero(bag: Bag) : Character {
    // 다른 멤버 변수와 메서드들...

    fun takeItem(item: Item) {
        bag.takeItem(item) // 중복 로직을 갖는 객체에게 객체 전달(위임)
    }
}

 

더보기
// 방어구 클래스
class Armor(val defensePoint: Int) {
    // 공격을 받았을 때 방어구에 의한 피해 감소 계산
    fun getDefensedDamage(damage: Int): Int {
        return damage - defensePoint
    }
}

// 캐릭터 클래스
class Character(val armor: Armor?) {
    // 공격력
    val damage = 10
    // 체력
    var healthPoint = 100

    // 공격을 실행하는 함수
    fun attack(target: Character) {
        target.takeAttack(damage)
    }

    // 공격을 받는 함수
    fun takeAttack(damage: Int) {
        // 만약 방어구가 있다면 방어구의 방어력을 적용하여 피해 계산
        val defensedDamage = armor?.getDefensedDamage(damage) ?: damage
        // 계산된 피해만큼 체력을 감소시킴
        healthPoint -= defensedDamage
    }
}

fun main() {
    // 방어구가 없는 캐릭터 생성(캐릭터 클래스 사용)
    val characterWithoutArmor = Character(null)
    // 방어구가 있는 캐릭터 생성(캐릭터 클래스와 아머 클래스 조합)
    val characterWithArmor = Character(Armor(3))

    // 방어구 없는 캐릭터가 공격을 받음
    characterWithoutArmor.takeAttack(10)
    println(characterWithoutArmor.healthPoint) // 출력: 90

    // 방어구 있는 캐릭터가 공격을 받음
    characterWithArmor.takeAttack(10)
    println(characterWithArmor.healthPoint) // 출력: 97
}

상속의 함정

 

1. 커플링(Coupling)

상속을 통해 부모 클래스와 자식 클래스 간에 강한 의존성이 생깁니다. 부모 클래스의 변경이 자식 클래스에도 영향을 미치므로 부모 클래스의 수정이 전체 시스템에 미치는 영향을 파악하기 어려워집니다.

 

2. 클래스의 복잡성 증가

다중 상속을 사용하거나 상속 계층이 깊어질수록 클래스의 복잡성이 증가합니다. 이는 코드를 이해하고 유지보수하기 어렵게 만듭니다.

 

3. 하위 클래스 결합도 증가

상속을 통해 하위 클래스가 상위 클래스에 결합되면, 하위 클래스의 변경이 상위 클래스에도 영향을 줄 수 있습니다. 이는 유연성을 저하시키고, 재사용성을 감소시킵니다.

 

4. 설계 변경의 어려움

상속 계층 구조를 변경하려면 많은 클래스 간의 관계를 고려해야 합니다. 이는 설계 변경을 어렵게 만들며, 변경의 위험성을 증가시킵니다.

 

5. 상위 클래스의 변경의 위험

상위 클래스의 변경이 하위 클래스에 영향을 미칠 수 있습니다. 따라서 상위 클래스를 수정할 때는 하위 클래스들의 동작에 대한 영향을 신중하게 고려해야 합니다.