Principios SOLID en Rust: teoría y práctica de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: SOLID y Rust — una combinación ideal

\n

Los principios SOLID son reglas fundamentales del diseño orientado a objetos que ayudan a crear código flexible, mantenible y escalable. Aunque Rust no es un lenguaje puramente orientado a objetos (utiliza traits y estructuras en lugar de clases), los principios SOLID son totalmente aplicables a él. En este artículo, analizaremos cada uno de los cinco principios con ejemplos de código en Rust, mostrando cómo ayudan a construir sistemas robustos.

\n

A lo largo del artículo, verá cómo Rust, con su sistema de propiedad, traits y genéricos, hace que la implementación de SOLID sea natural y potente. Comenzaremos con Single Responsibility y terminaremos con Dependency Inversion, proporcionando ejemplos listos para usar.

\n\n

1. Single Responsibility Principle (SRP) — principio de responsabilidad única

\n

Esencia: Cada módulo, clase o función debe tener solo una razón para cambiar. En Rust, esto significa que una estructura debe encargarse de una sola tarea.

\n\n

Ejemplo incorrecto (violación de SRP)

\n
struct Report {\n    title: String,\n    content: String,\n}\n\nimpl Report {\n    fn generate(&self) -> String {\n        format!("# {}\\n\\n{}", self.title, self.content)\n    }\n\n    fn save_to_file(&self, path: &str) -> std::io::Result<()> {\n        std::fs::write(path, self.generate())?;\n        Ok(())\n    }\n\n    fn send_email(&self, recipient: &str) {\n        println!("Sending email to {} with report", recipient);\n    }\n}
\n

Aquí, la estructura Report se encarga de la generación, el guardado y el envío — tres razones diferentes para cambiar. Esto viola SRP.

\n\n

Ejemplo correcto (cumplimiento de SRP)

\n
struct Report {\n    title: String,\n    content: String,\n}\n\nimpl Report {\n    fn generate(&self) -> String {\n        format!("# {}\\n\\n{}", self.title, self.content)\n    }\n}\n\nstruct ReportSaver;\n\nimpl ReportSaver {\n    fn save(&self, report: &Report, path: &str) -> std::io::Result<()> {\n        std::fs::write(path, report.generate())?;\n        Ok(())\n    }\n}\n\nstruct EmailSender;\n\nimpl EmailSender {\n    fn send(&self, recipient: &str, message: &str) {\n        println!("Sending email to {}: {}", recipient, message);\n    }\n}
\n

Ahora cada estructura se encarga de su propia tarea: Report — de los datos y la generación, ReportSaver — del guardado, EmailSender — del envío. Esto simplifica las pruebas y el mantenimiento.

\n\n

2. Open-Closed Principle (OCP) — principio de abierto/cerrado

\n

Esencia: Las entidades de software deben estar abiertas para la extensión, pero cerradas para la modificación. En Rust, esto se logra mediante traits y genéricos.

\n\n

Ejemplo: sistema de filtrado

\n
trait Filter<T> {\n    fn apply(&self, items: &[T]) -> Vec<T>;\n}\n\nstruct EvenFilter;\n\nimpl Filter<i32> for EvenFilter {\n    fn apply(&self, items: &[i32]) -> Vec<i32> {\n        items.iter().filter(|&x| x % 2 == 0).copied().collect()\n    }\n}\n\nstruct GreaterThanFilter {\n    threshold: i32,\n}\n\nimpl Filter<i32> for GreaterThanFilter {\n    fn apply(&self, items: &[i32]) -> Vec<i32> {\n        items.iter().filter(|&&x| x > self.threshold).copied().collect()\n    }\n}\n\nfn process<T: Clone, F: Filter<T>>(items: &[T], filter: F) -> Vec<T> {\n    filter.apply(items)\n}\n\nfn main() {\n    let numbers = vec![1, 2, 3, 4, 5, 6];\n    let even = process(&numbers, EvenFilter);\n    let greater = process(&numbers, GreaterThanFilter { threshold: 3 });\n    println!("Even: {:?}, Greater: {:?}", even, greater);\n}
\n

Podemos agregar nuevos filtros sin modificar el código existente de process. Esta es una implementación de OCP mediante polimorfismo de traits.

\n\n

3. Liskov Substitution Principle (LSP) — principio de sustitución de Barbara Liskov

\n

Esencia:

Blogs

Book Recommendations