Skip to content

Instantly share code, notes, and snippets.

@vitalikas
Created November 20, 2025 08:40
Show Gist options
  • Select an option

  • Save vitalikas/68b1796514b72d820a0669f13b263ac7 to your computer and use it in GitHub Desktop.

Select an option

Save vitalikas/68b1796514b72d820a0669f13b263ac7 to your computer and use it in GitHub Desktop.
SOLID example
interface SortingStrategy<T : Comparable<T>> {
fun sort(data: List<T>): List<T>
}
enum class StrategyType {
BUBBLE, MERGE, QUICK
}
class BubbleSortStrategy<T : Comparable<T>> : SortingStrategy<T> {
override fun sort(data: List<T>): List<T> {
// bubble sort implementation
return data
}
}
class MergeSortStrategy<T : Comparable<T>> : SortingStrategy<T> {
override fun sort(data: List<T>): List<T> {
// merge sort implementation
return data
}
}
class QuickSortStrategy<T : Comparable<T>> : SortingStrategy<T> {
override fun sort(data: List<T>): List<T> {
// quick sort implementation
return data.sorted()
}
}
class SortingFactory<T : Comparable<T>>(
private val strategies: Map<StrategyType, SortingStrategy<T>>
) {
fun sort(
type: StrategyType,
data: List<T>
): List<T> {
val strategy = strategies[type] ?: error("Sorting strategy '$type' not registered")
return strategy.sort(data)
}
}
val factoryInt = SortingFactory<Int>(
mapOf(
StrategyType.BUBBLE to BubbleSortStrategy(),
StrategyType.MERGE to MergeSortStrategy(),
StrategyType.QUICK to QuickSortStrategy(),
)
)
val sorted = factoryInt.sort(StrategyType.QUICK, listOf(3, 1, 2))
fun main() {
println("Sorted list: $sorted, using ${StrategyType.QUICK} strategy")
}
/**
* 1. Single Responsibility Principle SRP
* Each class has one responsibility:
* SortingStrategy<T> is an interface that defines a contract for sorting.
* BubbleSortStrategy, MergeSortStrategy, and QuickSortStrategy each implement a specific sorting algorithm.
* SortingFactory<T> is responsible for managing available strategies and delegating the sorting work.
* Each class does one thing and does it well.
*
* 2. Open/Closed Principle OCP
* Classes are open for extension, closed for modification:
* You can add new sorting algorithms by creating new classes implementing SortingStrategy<T> e.g., add a HeapSortStrategy without modifying SortingFactory or any existing sorting strategy.
* The SortingFactory works with any SortingStrategy<T>, making it extensible.
*
* 3. Liskov Substitution Principle LSP
* Subtypes are substitutable for their base types:
* You can use any class that implements SortingStrategy<T> wherever a SortingStrategy<T> is expected.
* The factory deals with strategies through their shared interface, not specific implementations.
*
* 4. Dependency Inversion Principle DIP
* High-level modules should depend on abstractions:
* SortingFactory depends on the abstraction SortingStrategy<T>, not concrete sorting implementations.
* You can provide any strategy to the factory without changing its implementation.
*
* 5. Interface Segregation Principle ISP
* In this context, ISP is followed by default: There is only one interface SortingStrategy<T> and it's minimal, so clients are not forced to depend on things they don't use.
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment