Kotlin: Ordenando | Ubicación de la operación de intercambio

Estoy implementando el algorithm Quicksort en Kotlin. Para eso, creé una interfaz, ISort , con un parámetro de tipo y una única function, orderar . Para orderar, necesito la operación de intercambio. Me preguntaba cuál es la mejor location de esta function de intercambio. Mis ideas:

1) Desafortunadamente, en Kotlin no se puede proteger la function de interfaz. Por lo tanto, cada class podría ver el cambio en sus implementaciones y eso no es demasiado agradable (aunque tampoco está mal, estoy de acuerdo).

2) Ponerlo en la implementación de QuickSort es aún peor porque podría haber varias implementaciones de la interfaz ISort que necesitan una function de intercambio.

3) Mi siguiente pensamiento fue crear un object singleton pero Kotlin permite objects con parameters de tipo.

Aquí está la definición de la interfaz:

interface ISort<T> { fun sort(toSort: MutableList<T>): MutableList<T> // 1) Putting swap here has a too high visibility } 

Y aquí está el esqueleto de la class QuickSort:

 class QuickSort<T> : ISort<T> { override fun sort(toSort: MutableList<T>): MutableList<T> { doQuickSort(toSort) // Internally uses swap return toSort } // 2) Putting swap here might lead to code duplication of swap } 

Entonces, desde una perspectiva de ingeniería de software, cuál sería el mejor lugar / location para la operación de intercambio.

Funciones de nivel superior

En un file sort.kt o así,

 package abc.def.sort fun <T> quicksort(list: MutableList<T>): MutableList<T> { ... } // invisible in other files, but visibie in "sort.kt" private fun <T> swap(...) { ... } 

Para utilizar la function de swap de otras forms, deberá definir otras funciones de orderación en el mismo file. (O copie la function de swap muchas veces).

Esto se recomienda para funciones muy simples.

Objeto como espacio de nombres

Esto es similar al método anterior, pero más OOP-ish que el anterior.

 object QuickSort { fun <T> sort(list: MutableList<T>): MutableList<T> { ... } private fun <T> swap(...) { ... } } 

o

 object Sorts { fun <T> quicksort(list: MutableList<T>): MutableList<T> { ... } // add other sort methods... private fun <T> swap(...) { ... } } 

Sin embargo, esto no se recomienda en Kotlin ( Mejores prácticas para declaraciones de alto nivel ).

Combinación de class abstracta y object

La function de swap se puede reutilizar para otros géneros de esta forma.

 abstract class Sort { abstract fun <T> sort(list: MutableList<T>): MutableList<T> protected fun <T> swap(...) { ... } } object QuickSort : Sort() { override fun <T> sort(list: MutableList<T>): MutableList<T> { ... } } 

Creo que [hacer que el parámetro de tipo T sea ​​un parámetro de tipo de class, no un parámetro de tipo de function] hará que el problema sea innecesariamente más complejo porque tendrá que crear una instancia de class para cada vez que utilice un tipo diferente de T