Reputation: 184
I'm implementing the Quicksort algorithm in Kotlin. For that, I created an interface, ISort, with a type parameter and a single function, sort. For sorting, I need the swap operation. I was wondering what the best location of this swap function is. My ideas:
1) Unfortunately, in Kotlin one cannot make interface function protected. Thus, every class could see the swap in its implementations and that's not too nice (although it's not too bad either, I agree).
2) Putting it in the QuickSort implementation is even worse because there might be several implementations of the ISort interface that need a swap function.
3) My next thought was to create a singleton object but Kotlin permits objects with type parameters.
Here is the interface definition:
interface ISort<T> {
fun sort(toSort: MutableList<T>): MutableList<T>
// 1) Putting swap here has a too high visibility
}
And here is the skeleton of the QuickSort class:
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
}
So, from a software engineering perspective what would be the best place / location for the swap operation.
Upvotes: 1
Views: 367
Reputation: 15572
In a file sort.kt
or so,
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(...) {
...
}
To use the swap
function in other sorts, you will need to define other sort functions in the same file. (Or copy the swap
function many times.)
This is recommended for very simple functions.
This is similar to the method above, but more OOP-ish than the previous one.
object QuickSort {
fun <T> sort(list: MutableList<T>): MutableList<T> {
...
}
private fun <T> swap(...) {
...
}
}
or
object Sorts {
fun <T> quicksort(list: MutableList<T>): MutableList<T> {
...
}
// add other sort methods...
private fun <T> swap(...) {
...
}
}
However, this is not recommended in Kotlin (Best practices for top-level declarations).
The swap
function can be reused for other sorts in this way.
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> {
...
}
}
I think [making the type parameter T
be a class type parameter, not a function type parameter] will make the problem unnecessarily more complex because you will have to create a class instance for each time you use different type T
.
Upvotes: 1