객체들의 관계를 트리 구조로 구성하여 부분-전체(Part-Whole) 계층을 표한하는 패턴
단일 객체와 복합 객체 모두 동일하게 다루도록 한다.
Component
를 구현하여 필요한 함수를 사용하고 하나의 Leaf 로 구성할 수 있도록 Interface를 만들어 객체를 생성한다.
interface Component {
fun getWeight(): Int
fun getItemCount(): Int
fun getItemName(): String
}
아이템의 전체 구성요소가 될 Interface 를 만든다.
Component
인터페이스의 경우 Item에 반드시 필요한 객체의 상태를 구현하면 된다.
class M4A1: Component {
override fun getWeight(): Int {
return 3800
}
override fun getItemCount(): Int {
return 1
}
override fun getItemName(): String {
return "M4A1"
}
}
class Bullet_5(private val count: Int) : Component {
override fun getWeight(): Int {
return 5 * getItemCount()
}
override fun getItemCount(): Int {
return count
}
override fun getItemName(): String {
return "5.56mm"
}
}
... (생략)
간단하게 총과 총알을 사용하는 Item Class 를 만들었다.
Component
인터페이스를 상속받아 구현하는 구현체를 작성한다.
각 아이템의 무게, 개수, 이름을 입력한 Leaf 를 만들 수 있다.
class BattlegroundBag(
private val name: String
) : Component {
private val _components: ArrayList<Component> = arrayListOf()
fun addItem(component: Component) {
_components.add(component)
}
fun hasItemList(): String {
val iter = _components.iterator()
val sb = StringBuilder()
while (iter.hasNext()) {
sb.append(iter.next().getItemName())
.append(", ")
}
sb.delete(sb.lastIndex - 1, sb.lastIndex)
return sb.toString()
}
override fun getWeight(): Int {
return _components.sumOf { it.getWeight() }
}
override fun getItemCount(): Int {
return _components.sumOf { it.getItemCount() }
}
override fun getItemName(): String {
return name
}
}
Compostite
클래스인 BattlegroundBag
의 는 Leaf 를 저장할 수 있는 _components
리스트가 있고 가방안에 있는 모든 아이템의 무게와 갯수를 출력할 수 있도록 구현하게 되었고
가방안에 있는 Item의 종류를 출력해주는 함수도 존재합니다.
이처럼 Leaf / Tree 구조를 통해 전체와 부분을 하나의 객체처럼 사용할 수 있도록 구현하게 됩니다.
class Battleground {
init {
val level3Bag = BattlegroundBag("3레벨 가방")
val m4 = M4A1()
val Kar98 = Kar98()
val bullet5 = Bullet_5(120)
val bullet7 = Bullet_7(30)
level3Bag.addItem(m4)
level3Bag.addItem(Kar98)
level3Bag.addItem(bullet5)
level3Bag.addItem(bullet7)
println(level3Bag.getItemName())
println("가방의 총 무게 : " + level3Bag.getWeight() + "g")
println("아이템 리스트 : " + level3Bag.hasItemList())
println("총알 개수")
println("5탄 : ${bullet5.getItemCount()}, 7탄 : ${bullet7.getItemCount()}")
}
}
private fun main() {
Battleground()
}
컴포짓 패턴의 경우 전체-부분 의 개념으로 객체를 접근하도록 구현하는 패턴입니다.
트리 구조로 만들어야하는 제약이 존재 하지만, 하나의 객체를 그룹 또는 각각의 객체로 사용하기 편하기 때문에 사용하게 됩니다.