Rust - Es un Lenguaje Orientado a Objetos?

Iniciado por Khala, Septiembre 27, 2021, 04:29:19 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

En este articulo, vamos a explorar la Programacion orientada a objetos (OOP) en Rust y cubrir temas como Objeto, Encapsulacion, Herencia, Polimorfismo y otros junto con ejemplos de codigo en Rust.

Contenidos:


  • Introduccion a la OOP
  • Que es Rust?
  • Objetos y Encapsulacion
  • Herencia y Polimorfismo


Empecemos con Programación orientada a objetos.

Introduccion a OOP.
La programación orientada a objetos es un termino que existe desde 1967, creado por Alan Key. En la arquitectura orientada a objetos, el codigo está estructurado en Objetos, que se comunnican entre ellos a traves de interfaces publicas, pero no saben como funcionan los demás internamente.

Esto hace que el programador pueda evitar preocuparse sobre como estan implementados internamente los objetos con los cuales está interactuando. E incluso si esa implementacion cambiara, o fuera totalmente desconocida, mientras las funciones de la interfaz publica no cambien, puede estar seguro que su codigo va a seguir funcionando (A menos que la implementacion esté mal, en cuyo caso.. bueno, no hay mucho que hacer!)

Qué es Rust?
Antes de seguir avanzando... Qué es Rust?



El lenguaje de programacion Rust te ayuda a escribir software que es más rapido y más seguro. En general, control de bajo nivel y facilidad de escritura suelen estar opuestas en el diseño de lenguaje de programacion. Rust desafia este problema. Balanceando  una poderosa capcidad tecnica con la experiencia del developer, Rust te da la opcion de controlar los detalles de bajo nivel (como el uso de memoria) sin los problemas tradicionalmente asociados a dicho control.

Con eso dicho, hay muchas definiciones para la Programacion orientada a objetos (OOP a partir de ahora, por su sigla en ingles), y dependiendo de cual elijas usar, Rust puede ser o no ser un lenguaje OOP. Muchos lenguajes OOP comparten ciertan caracteristicas, como Objetos, Herencia, Encapsulacion...

Veamos como Rust lidia e implementa estas cosas! (Los ejemplos de código estan sacados directamente del Libro de Rust, linkeado al final de este articulo).

Objetos y Encapsulacion

En el libro Design Patterns: Elements of Reusable Object-Oriented Software de Erich Gamma, Richard Helm, Ralph Johnson, y John Vlissides (Addison-Wesley Professional, 1994), los objetos son definidos como:

Programas OOP estan compuestos de objetos. Un objeto empaca tanto datos como los procedimientos que operan con esa data. Los procedimientos son tipicamente llamados metodos u operaciones (O funciones, más tradicionalmente hoy dia)

Usando esta definicion, Rust es un lenguaje OOP. Rust tiene structs y blowues impl que pueden ser usados para almanecar datos y formas de operar con ellos respectivamente.

Código: php
pub struct AveragedCollection {
    list: Vec<i32>,
    average: f64,
}

impl AveragedCollection {
    pub fn add(&mut self, value: i32) {
        self.list.push(value);
        self.update_average();
    }

    pub fn remove(&mut self) -> Option<i32> {
        let result = self.list.pop();
        match result {
            Some(value) => {
                self.update_average();
                Some(value)
            }
            None => None,
        }
    }

    pub fn average(&self) -> f64 {
        self.average
    }

    fn update_average(&mut self) {
        let total: i32 = self.list.iter().sum();
        self.average = total as f64 / self.list.len() as f64;
    }
}


Como se puede ver en el codigo de arriba, tenemos una estructura (el bloque struct) y un bloque de implementacion (el bloque impl). Ésta estructura es comparable a una clase en C# o cualquier otro lenguaje similar. El bloque impl es esencialmente donde las funciones que uno pondria dentro de esa clase.

La estructura esta marcada pub (publica) lo que significa que otro codigo externo a esta estructura puede usarla, pero los camps internos son privados. Esto significa que los datos están encapsulados dentro del 'Objeto' struct. Las funciones add(para agregar), remove( para remover) y promedio (average) tambien estan marcadas como pub, lo cual expone esta interfaz al mundo exterior. Mientras, update_average (actualizar el promedio) se mantiene privada, lo que significa que solo el objeto/estructura AveragedCollection puede usarla. Lo cual tiene sentido. Solo la coleccion deberia ser capaz de actualizar sus propios datos. Esto elimina el problema de terceros alterando los datos de la coleccion sin nuestro conocimiento. Lo cual nos da otro beneficio. Si algo esta mal con los datos, sabemos que el error debe estar en la estructura o en su implementacion, y no en cualquier otro lado de nuestro programa. Esto es uno de los pilares de la programacion SOLID; lo cual está fuera de los contenidos de este articulo, pero puedo explayarme mas en otro, si fuera necesario o pedido)


Herencia y Polimorfismo
La herencia es un mecanismo por el cual un objeto puede heredar parte de su definicion de la de otro objeto, lo cual le da los datos y comporatmiento de su padre, sin tener que definirlos nuevamente.

Considerando herencia, Rust no tiene forma de especficiar que una estructura hereda atributos o funcionalidad de otra. Entonces en este sentido, Rust NO es un lenguaje OOP. No obstante, hay otras soluciones que Rust ofrece que son similares a herencia, por ejemplo, Traits.

Un trait le dice al compilador de Rust sobre funcionalidad que un tipo en particular tiene y puede compartir con otros tipos. Podemos usar Traits para definir comportamiento compartido en una forma abstracta. Podemos usar Traits tambien para especificar que un tipo generico tiene que tener si o si cierta funcionalidad o comportamiento. (Si ya conocen OOP, piensen en una Interfaz. Es esencialmente lo mismo)

Código: php
pub trait Summary {
    fn summarize(&self) -> String;
}


Esto es un ejemplo de un Trait. Tal como una Interfaz en otros lenguajes, cualquier clase o estructura en el caso de Rust que use esto, DEBE OBLIGATORIAMENTE implementarlo en algun lugar de su propia definicion. Un trait puede tener multiples metodos en su cuerpo, y cualquiera que lo use deberá implementarlos todos.

La implementacion se veria algo asi...


Código: php
pub struct NewsArticle {
    pub headline: String,
    pub location: String,
    pub author: String,
    pub content: String,
}

impl Summary for NewsArticle {
    fn summarize(&self) -> String {
        format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
}


A veces es util o necesario tener algun tipo de implementacion por defecto para estos, lo cual es posible:

Código: php
pub trait Summary {
    fn summarize(&self) -> String {
        String::from("(Read more...)")
    }
}


Si queremos usar la implementacion por defecto, se deja el bloque impl vacío. El compilador entenderá que la ausencia de implementacion implica que se usará la implementacion por defecto.

Para mucha gente, polimorfismo es un sinonimo de herencia. Pero en realidad es un concepto mas general que refiere a codigo que puede trabajar con datos de multiples tipos. Para Herencia, estos tipos suelen ser sub-clases.

Rust en cambio usa Generics para abastraer diferentes tipos posibles, y Traits para imponer restricciones sobre que cosas esos tipos deben proveer.

Usando structs, traits y bloques impl, uno puede codear en un estilo OOP, pero como pueden ver, es dificil decir definitivamente si Rust es o no es un lenguaje OOP. En mi opinion, Rust es un lenguaje versátil que de ser necesario, puede ser OOP. Pero si querés aprender sobre el estilo de diseño OOP, es mejor hacerlo con lenguajes más tradicionales en esto, como por ejemplo C#, Java, o incluso C++ (Si eres valiente).

Les pregunto.. Conocen Rust? Han oido hablar de este lenguaje de programacion? Cree que cumple los requisitos para ser OOP?

Link al articulo Original (Con algunos cambios, tambien en ingles, escrito por mi para OpenGenus y traducido tambien por mi para Underc0de) No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Link al libro de Rust (En ingles) No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Gracias por Leer!