Задача
Представьте, что у вас есть SimpleAdapter
. Его конструктор занимает List<Item>
. И у него есть метод open fun getItemAt(pos:Int):Item
Теперь вы хотите создать StickableAdapter
. Некоторые специальные предметы всегда будут липкими сверху. И когда пользователи используют связанные с индексами методы StickableAdapter
, мы хотим, чтобы пользователи не знали об этом факте, например, не знали об этом. компенсируя смещение в этих методах.
Как лучше всего это делать?
Первоначальное решение и его проблема
Естественная мысль -
class StickableAdapter(
var specialItems: List<Item>,
initialItems: List<Item>
): SimpleAdapter(specialItems + initialItems){
override fun getItemAt(pos: Items): Item{
return super.getItemAt(pos + specialItems.count())
}
}
Но это испортит логику в SimpleAdapter
, так как все предыдущие вызовы getItemAt
в SimpleAdapter
будут перенаправлены на новый метод переопределения, что приведет к хаосу. Мы хотим, чтобы эти внутренние вызовы в SimpleAdapter
оставались такими, какие они есть, и переопределяли только те, которые были выставлены пользователю.
Разделение getItemsAt
на private fun getItemsAtPrivate()
и open fun getItemsAtPublic()
также не очень хорошая идея. Потому что в будущем я могу делать абстракции поверх StickableAdapter
.
Некоторые проблемы, характерные для RecyclerView.Adapter
На самом деле, у Котлина есть шаблон делегирования, который, на мой взгляд, решил бы проблему. Мне просто нужно
class StickableAdapter(val delegate: SimpleAdapter): IAdapter by delegate{
constructor(
var specialItems: List<Item>,
initialItems: List<Item>
): this(SimpleAdapter(specialItems + initialItems))
fun getItemAt(pos: Items): Item{
return delegate.getItemAt(pos + specialItems.count())
}
}
Работает отлично. Но шаблон делегирования Kotlin работает только для интерфейсов. И RecyclerView не предоставил и не принял интерфейс IAdapter
для работы.
Я просто хочу знать, как вы, ребята, на практике кладете абстракции поверх абстракций. Любой совет по этой теме приветствуется.