Skip to content

Commit

Permalink
Merge pull request mouredev#6001 from eulogioep/main
Browse files Browse the repository at this point in the history
#26 y 27 Kotlin
  • Loading branch information
Roswell468 authored Sep 9, 2024
2 parents 2fa8405 + eaacbda commit d5ae690
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 0 deletions.
130 changes: 130 additions & 0 deletions Roadmap/26 - SOLID SRP/kotlin/eulogioep.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Principio de Responsabilidad Única (SRP)
*
* El Principio de Responsabilidad Única es el primer principio de SOLID y establece que una clase
* debe tener una, y solo una, razón para cambiar. En otras palabras, una clase debe tener una
* única responsabilidad bien definida.
*
* Este principio promueve la modularidad, facilita el mantenimiento y mejora la legibilidad del código.
* Cuando una clase tiene múltiples responsabilidades, se vuelve más difícil de entender, modificar y probar.
*/

// Definiciones de datos comunes
data class Book(val title: String, val author: String, var availableCopies: Int)
data class User(val name: String, val id: String, val email: String)
data class Loan(val user: User, val book: Book)

// Versión que no cumple con SRP
class LibraryWithoutSRP {
private val books = mutableListOf<Book>()
private val users = mutableListOf<User>()
private val loans = mutableListOf<Loan>()

fun addBook(title: String, author: String, copies: Int) {
books.add(Book(title, author, copies))
}

fun registerUser(name: String, id: String, email: String) {
users.add(User(name, id, email))
}

fun loanBook(userId: String, bookTitle: String) {
val user = users.find { it.id == userId }
val book = books.find { it.title == bookTitle }
if (user != null && book != null && book.availableCopies > 0) {
loans.add(Loan(user, book))
book.availableCopies--
}
}

fun returnBook(userId: String, bookTitle: String) {
val loan = loans.find { it.user.id == userId && it.book.title == bookTitle }
if (loan != null) {
loans.remove(loan)
loan.book.availableCopies++
}
}
}

// Versión refactorizada que cumple con SRP
class BookManager {
private val books = mutableListOf<Book>()

fun addBook(title: String, author: String, copies: Int) {
books.add(Book(title, author, copies))
}

fun findBook(title: String): Book? = books.find { it.title == title }
}

class UserManager {
private val users = mutableListOf<User>()

fun registerUser(name: String, id: String, email: String) {
users.add(User(name, id, email))
}

fun findUser(id: String): User? = users.find { it.id == id }
}

class LoanManager {
private val loans = mutableListOf<Loan>()

fun loanBook(user: User, book: Book) {
if (book.availableCopies > 0) {
loans.add(Loan(user, book))
book.availableCopies--
}
}

fun returnBook(user: User, book: Book) {
val loan = loans.find { it.user == user && it.book == book }
if (loan != null) {
loans.remove(loan)
book.availableCopies++
}
}
}

class Library(
private val bookManager: BookManager,
private val userManager: UserManager,
private val loanManager: LoanManager
) {
fun addBook(title: String, author: String, copies: Int) {
bookManager.addBook(title, author, copies)
}

fun registerUser(name: String, id: String, email: String) {
userManager.registerUser(name, id, email)
}

fun loanBook(userId: String, bookTitle: String) {
val user = userManager.findUser(userId)
val book = bookManager.findBook(bookTitle)
if (user != null && book != null) {
loanManager.loanBook(user, book)
}
}

fun returnBook(userId: String, bookTitle: String) {
val user = userManager.findUser(userId)
val book = bookManager.findBook(bookTitle)
if (user != null && book != null) {
loanManager.returnBook(user, book)
}
}
}

// Uso del sistema refactorizado
fun main() {
val bookManager = BookManager()
val userManager = UserManager()
val loanManager = LoanManager()
val library = Library(bookManager, userManager, loanManager)

library.addBook("1984", "George Orwell", 5)
library.registerUser("EulogioEP", "001", "[email protected]")
library.loanBook("001", "1984")
library.returnBook("001", "1984")
}
76 changes: 76 additions & 0 deletions Roadmap/27 - SOLID OCP/kotlin/eulogioep.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Principio Abierto-Cerrado (OCP) de SOLID
*
* El principio OCP establece que las entidades de software (clases, módulos, funciones, etc.)
* deben estar abiertas para la extensión, pero cerradas para la modificación. Esto significa
* que debemos poder extender el comportamiento de una clase sin modificar su código existente.
*
* En este ejemplo, demostraremos cómo aplicar el OCP en el diseño de una calculadora,
* permitiendo agregar nuevas operaciones sin modificar el código existente.
*/

// Interfaz que define la operación matemática
interface Operation {
fun execute(a: Double, b: Double): Double
}

// Implementaciones de las operaciones básicas
class Addition : Operation {
override fun execute(a: Double, b: Double) = a + b
}

class Subtraction : Operation {
override fun execute(a: Double, b: Double) = a - b
}

class Multiplication : Operation {
override fun execute(a: Double, b: Double) = a * b
}

class Division : Operation {
override fun execute(a: Double, b: Double): Double {
if (b == 0.0) throw IllegalArgumentException("Cannot divide by zero")
return a / b
}
}

// Calculadora que utiliza el principio OCP
class Calculator {
private val operations = mutableMapOf<String, Operation>()

fun addOperation(name: String, operation: Operation) {
operations[name] = operation
}

fun calculate(a: Double, b: Double, operationName: String): Double {
val operation = operations[operationName]
?: throw IllegalArgumentException("Operation not supported")
return operation.execute(a, b)
}
}

// Ejemplo de uso y prueba
fun main() {
val calculator = Calculator()

// Agregar operaciones básicas
calculator.addOperation("add", Addition())
calculator.addOperation("subtract", Subtraction())
calculator.addOperation("multiply", Multiplication())
calculator.addOperation("divide", Division())

// Probar operaciones básicas
println("5 + 3 = ${calculator.calculate(5.0, 3.0, "add")}")
println("5 - 3 = ${calculator.calculate(5.0, 3.0, "subtract")}")
println("5 * 3 = ${calculator.calculate(5.0, 3.0, "multiply")}")
println("6 / 3 = ${calculator.calculate(6.0, 3.0, "divide")}")

// Agregar una nueva operación (potencia) sin modificar el código existente
class Power : Operation {
override fun execute(a: Double, b: Double) = Math.pow(a, b)
}
calculator.addOperation("power", Power())

// Probar la nueva operación
println("2^3 = ${calculator.calculate(2.0, 3.0, "power")}")
}

0 comments on commit d5ae690

Please sign in to comment.