Created
November 20, 2025 08:40
-
-
Save vitalikas/68b1796514b72d820a0669f13b263ac7 to your computer and use it in GitHub Desktop.
SOLID example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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