¿Qué es el patrón MVC en programación y por qué es útil?

15/10/2019
Artículo original

Imagen ornamental que muestras unas fichas de scrabble con las letras MVC. Elaboración propia de campusMVP

ASP.NET Core MVC es el marco de trabajo creado por Microsoft, y una gran comunidad de desarrolladores, que permite desarrollar aplicaciones para la web con arquitectura Modelo-Vista-Controlador sobre la plataforma ASP.NET Core. Desde luego, no es el primer ni único, framework MVC para crear aplicaciones usando el patrón Modelo-Vista-Controlador. Ni siquiera es el primero que se crea con tecnologías Microsoft, ya que con .NET "Clásico" hace muchos años que existe otro, precursor del actual.

En el artículo de hoy me voy a ocupar de ese, a veces llamado, patrón, arquitectura o incluso modelo MVC. Veremos qué es, algunas ideas equivocadas que existen sobre el mismo, qué partes tiene y cómo se relacionan entre sí, independientemente de la tecnología con la que se implemente...

Qué es el patrón MVC

MVC era inicialmente un patrón arquitectural, un modelo o guía que expresa cómo organizar y estructurar los componentes de un sistema software, sus responsabilidades y las relaciones existentes entre cada uno de ellos.

Su nombre, MVC, parte de las iniciales de Modelo-Vista-Controlador (Model-View-Controller, en inglés), que son las capas o grupos de componentes en los que organizaremos nuestras aplicaciones bajo este paradigma.

Es a menudo considerado también un patrón de diseño de la capa de presentación, pues define la forma en que se organizan los componentes de presentación en sistemas distribuidos.

Aunque el auge de este término durante los últimos tiempos pueda indicar lo contrario, MVC no es un concepto nuevo, ya que el patrón fue descrito en el año 1979 por Trygve Reenskaug, hoy en día profesor emérito de informática de la Universidad de Oslo, mientras trabajaba con el equipo de Smalltalk en los laboratorios Xerox PARC.

Por tanto, teniendo en cuenta su antigüedad, es obvio que ni siquiera fue ideado expresamente para sistemas web aunque ahora se use mucho en ellas. Existen implementaciones para todo tipo de sistemas (escritorio, clientes y servidores web, servicios web, Single Page Applications o SPA, etc.) y lenguajes (Smalltalk, Java, Ruby, C++, Python, PHP, JavaScript, NodeJS, etc.).

La arquitectura MVC propone, independientemente de las tecnologías o entornos en los que se base el sistema a desarrollar, la separación de los componentes de una aplicación en tres grupos (o capas) principales: el modelo, la vista, y el controlador, y describe cómo se relacionarán entre ellos para mantener una estructura organizada, limpia y con un acoplamiento mínimo entre las distintas capas.

El Modelo

Imagen ornamental. Letra M en el scrabble. elaboración propia de campusMVP.

En la capa Modelo encontraremos siempre una representación de los datos del dominio, es decir, aquellas entidades que nos servirán para almacenar información del sistema que estamos desarrollando. Por ejemplo, si estamos desarrollando una aplicación de facturación, en el modelo existirán las clases Factura, Cliente o Proveedor, entre otras.

Si nuestra aplicación forma parte de un sistema distribuido, es decir, consume servicios prestados por otros sistemas, en el Modelo encontraremos las clases de transferencia de datos (DTO, Data Transfer Objects) que nos permitirán intercambiar información con ellos.

Asimismo, encontraremos la lógica de negocio de la aplicación, es decir, la implementación de las reglas, acciones y restricciones que nos permiten gestionar las entidades del dominio. Será por tanto el responsable de que el sistema se encuentre siempre en un estado consistente e íntegro.

Por último, el Modelo será también el encargado de gestionar el almacenamiento y recuperación de datos y entidades del dominio, es decir, incluirá mecanismos de persistencia o será capaz de interactuar con ellos. Dado que habitualmente la persistencia se delega a un motor de bases de datos, es muy frecuente encontrar en el Modelo la implementación de componentes tipo DAL (Data Access Layer, o Capa de Acceso a Datos) y ORMs.

El Modelo contiene principalmente las entidades que representan el dominio, la lógica de negocio, y los mecanismos de persistencia de nuestro sistema.

La Vista

Imagen ornamental. Letra V en el scrabble. elaboración propia de campusMVP.

Los componentes de la Vista son los responsables de generar la interfaz de nuestra aplicación, es decir, de componer las pantallas, páginas, o cualquier tipo de resultado utilizable por el usuario o cliente del sistema. De hecho, suele decirse que la Vista es una representación del estado del Modelo en un momento concreto y en el contexto de una acción determinada.

Por ejemplo, si un usuario está consultando una factura a través de una aplicación web, la Vista se encargará de representar visualmente el estado actual de la misma en forma de página visualizable en su navegador. Si en un contexto B2B el cliente de nuestro sistema es a su vez otro sistema, la vista podría ser un archivo XML con la información solicitada. En ambos casos se trataría de la misma factura, es decir, la misma entidad del Modelo, pero su representación es distinta en función de los requisitos.

Cuando las vistas componen la interfaz de usuario de una aplicación, deberán contener los elementos de interacción que permitan al usuario enviar información e invocar acciones en el sistema, como botones, cuadros de edición o cualquier otro tipo de elemento, convenientemente adaptados a la tecnología del cliente.

En el caso de las aplicaciones para la Web, normalmente en la Vista se encontrarán los componentes capaces de generar el lenguaje de marcado de la página que será enviada al usuario.

En la Vista encontraremos los componentes responsables de generar la interfaz con el exterior, por regla general, aunque no exclusivamente, el UI de nuestra aplicación.

El Controlador

Imagen ornamental. Letra C en el scrabble. elaboración propia de campusMVP.

La misión principal de los componentes incluidos en el Controlador es actuar como intermediarios entre el usuario y el sistema. Serán capaces de capturar las acciones de éste sobre la Vista, como puede ser la pulsación de un botón o la selección de una opción de menú, interpretarlas y actuar en función de ellas. Por ejemplo, retornando al usuario una nueva vista que represente el estado actual del sistema, o invocando a acciones definidas en el Modelo para consultar o actualizar información.

Realizarán también tareas de transformación de datos para hacer que los componentes de la Vista y el Modelo se entiendan. Así, traducirán la información enviada desde la interfaz, por ejemplo los valores de campos de un formulario recibidos mediante el protocolo HTTP, a objetos que puedan ser comprendidos por el Modelo, como pueden las clases o las entidades del dominio.

Y de la misma forma, el Controlador tomará la información procedente del Modelo y la adaptará a formatos o estructuras de datos que la Vista sea capaz de manejar.

Por todo ello, podríamos considerar el Controlador como un coordinador general del sistema, que regula la navegación y el flujo de información con el usuario, ejerciendo también como intermediario entre la capa de Vista y el Modelo.

En el Controlador se encuentran los componentes capaces de procesar las interacciones del usuario, consultar o actualizar el Modelo, y seleccionar las Vistas apropiadas en cada momento.

Relación entre Modelo, Vista y Controlador

Nota: existen distintas variantes del patrón MVC. Aquí estamos considerando la utilizada más frecuentemente por los desarrolladores, aunque existe también la posibilidad de que la Vista contacte directamente con el Modelo, normalmente para obtener información.

El siguiente diagrama refleja las relaciones existentes entre los componentes del Modelo, Vista y Controlador, y de éstos a su vez con el usuario, o cliente, del sistema:

Interacción entre Modelo, Vista y Controlador

Como se muestra en el diagrama, las acciones e información procedentes del usuario serán recogidas exclusivamente por los Controladores. Ningún componente de otra capa debe acceder a los datos generados desde el cliente, de la misma forma que sólo los componentes de la Vista estarán autorizados a generar interfaces de usuario con las que enviar información de retorno.

Destaca también el papel central del Controlador. Tiene acceso bidireccional al Modelo, es decir, será capaz tanto de actualizar su estado, invocando por ejemplo métodos o acciones incluidos en su lógica de negocio, como de consultar la información que sea necesaria para completar sus tareas. Sin embargo, en ningún caso el Modelo será consciente o mostrará acoplamiento alguno respecto a las clases Controlador que lo están utilizando, ni conocerá las distintas representaciones (Vistas) que pueden realizarse de él cara al usuario.

Por otra parte, el Controlador es el encargado de seleccionar la Vista más apropiada en función de la acción llevada a cabo por el usuario, suministrándole toda la información que necesite para componer la interfaz. Para pasar esta información, el Controlador puede usar clases del Modelo o, lo que es más habitual, clases específicamente diseñadas para ello, denominadas View-Models, que contendrán toda la información que la Vista necesite para maquetarse y mantendrá a ésta aislada de los cambios en el Modelo.

La responsabilidad de la Vista, por tanto, se reduce a generar la interfaz partiendo de los datos que le suministre el controlador.

Ventajas y desventajas de patrón MVC

El uso del patrón MVC ofrece múltiples ventajas sobre otras maneras de desarrollar aplicaciones con interfaz de usuario, y en especial para la Web. Sin entrar en detalles aquí, por que la extensión del artículo ya es grande, comentaré a continuación algunas de ellas:

  • La clara separación de responsabilidades impuesta por el uso del patrón MVC hace que los componentes de nuestras aplicaciones tengan sus misiones bien definidas. Por lo tanto, nuestros sistemas serán más limpios, simples, más fácilmente mantenibles y, a la postre, más robustos.
  • Mayor velocidad de desarrollo en equipo, que es consecuencia de lo anterior, ya que al estar separado en tres partes tan diferenciadas, diferentes programadores pueden ocuparse de cada parte en paralelo. Esto la hace ideal para el desarrollo de aplicaciones grandes.
  • Múltiples vistas a partir del mismo modelo, pudiendo reaprovechar mucho mejor los desarrollos y asegurando consistencia entre ellas.
  • Facilidad para realización de pruebas unitarias.

Pero, por supuesto, no todo es siempre maravilloso, así que su uso presenta también algunas desventajas, entre las que cabe destacar:

  • Hay que ceñirse a las convenciones y al patrón. El uso de las convenciones impuestas por el framework y la estructura propuesta por el patrón arquitectural MVC nos obliga a ceñirnos a las mismas, lo que puede resultar a veces algo tedioso si lo comparamos con la forma habitual de trabajar con otros frameworks que dan más libertad al desarrollador. La división impuesta por el patrón MVC obliga a mantener un mayor número de archivos, incluso para tareas simples.
  • Curva de aprendizaje. Dependiendo del punto de partida, el salto a MVC puede resultar un cambio radical y su adopción requerirá cierto esfuerzo. Además, utilizarlo implica conocer bien las tecnologías subyacentes con las que se implemente: la plataforma de programación utilizada, además de la tecnología utilizada para la interfaz de usuario (HTML, CSS, JavaScript en el caso de la Web).

De todos modos, el uso del patrón MVC y sus variantes está claro que ha triunfado en todo tipo de desarrollos (Web, móvil, de escritorio...) y en todo tipo de plataformas (rara es la plataforma actual que no lo implementa para uno o varios tipos de desarrollos). En la actualidad no te puedes permitir el lujo de no conocerlo.

Ruby 2.4.8 publicado

10/10/2019
Artículo original

Ruby 2.4.8 ha sido publicado.

Esta versión incluye correcciones de seguridad. Por favor revise detalles en los temas siguientes.

Ruby 2.4 ahora está en fase de mantenimiento de seguridad, hasta el final de Marzo de 2020. Después de esa fecha, terminará el mantenimiento a Ruby 2.4. Le recomendamos comenzar a planear la migración a versiones más recientes de Ruby, tales como 2.6 o 2.5.

Actualización (Oct 2 4:00 UTC): Estamos resolviendo un problema que impide la instalación del .tar de la versión Ruby 2.4.8 como un usuario que no sea root. Vea actualizaciones detalladas siguiendo la [Falla #16197].

Descargas

  • https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.tar.bz2

    TAMAÑO: 12204030
    SHA1:   5f742a8df243fa4e216ff6f0c26cc8222a182459
    SHA256: e30eedd91386bec81489d2637522c9017aebba46f98e8b502f679df6b2f6a469
    SHA512: 2d7e0f5ad766e2a12a1b53ff838e6bfe86244ffb7202196769c25e9df6f71f3ccdd8605e7ef35c53e54310bc82caf6b368ad5111dd0a3ad70a3aae1a7be93f08
    
  • https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.tar.gz

    TAMAÑO: 13800260
    SHA1:   a13b0915b7fb3dd0fe1ed6a4e3640034038ba6c9
    SHA256: 37f0d180afa56ec3e7a3669c6f1b6ee8a47a811261f0e1afa8f817c8b577bd68
    SHA512: 4e5068b73356a9fa0bd2c8aaa261909039653c62dc363dd8b36c9c73b11b9c4e6ade752d7c67f1b38c00e27a4861f94ce696158bd210035ea0b417d0887a329b
    
  • https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.tar.xz

    TAMAÑO: 9813812
    SHA1:   adf24e0b0ad1755067435f21baa8d142bcaff5a9
    SHA256: a2a8f53ef14b891821dbbf67b081d7b9e223007a347000ff4a86a226a4708272
    SHA512: 5f51a8312c23c1c2bfbb9c59efbd789492a4a7e4b1d4e7764db6eaaa542008e814b40817f10825e22c7fa8715fb9187be5d09b06128da211559b3601785937ea
    
  • https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.8.zip

    TAMAÑO: 15322048
    SHA1:   756a206a5f91c1237432f693b157a6842039d760
    SHA256: a84e1c946761b1ed947194b6248a50f9aee21ca412dcd6021973951fd846a035
    SHA512: dcf7dead5baed4ffbd68016581ef1162f78729db9b5a49501a04d68d768e9138faa6e293c91dd9203a9a28d406bb236dd633688f1e96a07906e37db273ac8846
    

Comentario de la versión

Gracias a todos los que ayudaron con esta versión, especialmente, a quienes reportaron las vulnerabilidades.

Publicado por usa el 2019-10-01
Traducción de vtamara

Ruby 2.5.7 Publicado

10/10/2019
Artículo original

Ruby 2.5.7 ha sido publicado.

Esta versión incluye correcciones de seguridad. Por favor revise detalles en los temas siguientes.

Vea detalles en la bitácora de cambios.

Descargas

  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.bz2

    TAMAÑO: 13794351
    SHA1:   51154b6bfed967b5acd7903790402172ced2563b
    SHA256: e67c69b141ed27158e47d9a4fe7e59749135b0f138dce06c8c15c3214543f56f
    SHA512: 7d6a7d41b4f3789f46be5f996099f3eb8321aa4778b2a8ff44142654e769ba4ba2df127dd0f267547e4c8cd6ff46364f18e79838df54fcd7e3fb714294ee0099
    
  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.gz

    TAMAÑO: 15669771
    SHA1:   541039290d188fff683a1d2f2892bd74854dd022
    SHA256: 0b2d0d5e3451b6ab454f81b1bfca007407c0548dea403f1eba2e429da4add6d4
    SHA512: 6c4219e1ac316fb00cdd5ff2ac6292448e6ddf49f25eda91426f8e0072288e8849d5c623bf9d532b8e93997b23dddc24718921d92b74983aac8fdb50db4ee809
    
  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.xz

    TAMAÑO: 11296440
    SHA1:   dd6b2841334ee99250fdf6a29c4eda501df6be97
    SHA256: 201870e8f58957d542233fef588b1d76f7bf962fea44dcbd2237f4a5899a3f95
    SHA512: 63b7c75fab44cd1bd22f22ddec00c740cf379ac7240da0dfafcec54347766695faef47428ce1c433fd77fa96992e976c984697067fa526236d383b12adc9ce75
    
  • https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.zip

    TAMAÑO: 19051936
    SHA1:   2b761378ec667ca5980d37cb3c591bdf88c51e45
    SHA256: c56821bea150166c599195679c0629f8dfc16984aae0ed744bf306ef45abbd68
    SHA512: a5543a5b7dcee1d92c4edd874b1be92d5451402ce1320cc5c8f49188fa2243d70413f31b9e5cce7f434f1f37e6f8c3aef1be5407e5075eacbd7ca6836c67e6e3
    

Comentario de la versión

Gracias a todos los que ayudaron con esta versión.

El mantenimiento de Ruby 2.5, incluyendo esta versión, se basan en el “Acuerdo para una versión estable de Ruby” de la Asociación Ruby.

Publicado por usa el 2019-10-01
Traducción de vtamara

Ruby 2.6.5 Publicado

10/10/2019
Artículo original

Ruby 2.6.5 ha sido publicado.

Esta versión incluye correcciones de seguridad. Por favor revise detalles en los temas siguientes.

Vea los cambios en detalle en la bitacora de cambios.

Descargas

  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.bz2

    TAMAÑO: 14134619
    SHA1:   d959802f994594f3296362883b5ce7edf5e6e465
    SHA256: 97ddf1b922f83c1f5c50e75bf54e27bba768d75fea7cda903b886c6745e60f0a
    SHA512: 28e0b04ac8ca85203eb8939137b5e5de4850c933faf7f62fc69648fe1886faaabf6cdf48382f9d9585c1720876d10b41dafd33efaeb23341c309917fbd8a6e21
    
  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.gz

    TAMAÑO: 16172159
    SHA1:   1416ce288fb8bfeae07a12b608540318c9cace71
    SHA256: 66976b716ecc1fd34f9b7c3c2b07bbd37631815377a2e3e85a5b194cfdcbed7d
    SHA512: 7ab7a0cdaf4863152efc86dbcfada7f10ab3fe33590eee3b6ab7b26fc27835a8a0ded4ec02b58e9969175582a2be5410da3dc9f8694a3cd2db97708bd72773e1
    
  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.tar.xz

    TAMAÑO: 11553580
    SHA1:   575d3f68cbfa753fb07b538824711214f859b9c0
    SHA256: d5d6da717fd48524596f9b78ac5a2eeb9691753da5c06923a6c31190abe01a62
    SHA512: e8ae3b5d4d23a93d0ef6057235ad0e573665a8b4b6544e1c70b4cce9c4d2fb9094e5c8fe8a9ab7b9996efe3ada603f9b4ef1fd08fb5a83253c1ae2b5e3f202db
    
  • https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.5.zip

    TAMAÑO: 19839803
    SHA1:   66d850ea8275615b1282ef832c34645bbf9ebb16
    SHA256: 9455170dd264f69bd92ab0f4f30e5bdfc1ecafe32568114f1588a3850ca6e5fd
    SHA512: b9f54090f982695d92fc555cd1090db34496284edc69e335a16dea0d3189a33847464d1d1b701599bdabad0688efdf43cbbea41426f816a666d8ba7ccae6b5cf
    

Release Comment

Muchos contribuyentes, desarrolladores y usuarios han proveido reportes de fallas que nos han ayudado a hacer esta versión.

Gracias por sus contribuciones.

Publicado por nagachika el 2019-10-01
Traducción de vtamara

¿Cómo averiguar qué versión o versiones de la plataforma .NET tengo instaladas en mi equipo?

09/10/2019
Artículo original

A veces, quieres ejecutar o instalar una aplicación en una nueva máquina o en un servidor que no controlas, y tu aplicación escrita en .NET necesita una versión determinada.

Lo normal que cualquiera se preguntarías ¿dónde se ven las versiones instaladas? Seguro que hay un sitio en el que se muestra esta información o, en el peor de los casos, se puede lanzar algún comando desde la terminal del sistema que nos lo diga ¿verdad?

Por ejemplo, con .NET Core es muy sencillo, basta con escribir:

dotnet --version

Y lo obtenemos por pantalla:

La imagen muestra el resultado de la ejecución

Por desgracia, para .NET "clásico" no existe nada similar. Y es un dolor cuando quieres averiguarlo.

La única manera de hacerlo es complicada, implica leer el registro y obtener la versión de manera indirecta, y se gestiona de manera diferente según si es una versión de .NET anterior o posterior a la 4.5. Además hay que averiguar también en el registro si tiene aplicado o no algún "Service Pack". Como digo, un verdadero dolor, explicado por la propia Microsoft.

Pues bueno, para evitar este rollo lo que he hecho ha sido crear un programa de línea de comandos que lo haga automáticamente por nosotros y nos proporcione todas las versiones instaladas actualmente en el sistema. Se trata de DotNetVersions, y lo puedes encontrar en GitHub.

En realidad lo único que he hecho es convertir el código del artículo de Microsoft en un ejecutable que funcione correctamente con versiones antiguas del framework, porque no tiene mucho sentido ejecutarlo si para hacerlo ya necesitas tener al menos .NET 4 ¿no? Debería funcionar con .NET 1, pero como no tengo a mano ningún compilador para una versión tan vieja lo he adaptado y compilado para .NET 2.0 que en realidad está instalado en la práctica totalidad de los sistemas Windows del mundo.

Para ejecutarlo solo hay que llamarlo y te muestra por pantalla todas las versiones de .NET que haya en tu sistema:

La imagen muestra el programa en ejecución.

Por defecto muestra un encabezado (en inglés) junto a las versiones, y además se detiene hasta que pulses una tecla. Esto facilita el usarlo tan solo haciendo doble-clic sobre él.

Pero si por algún motivo necesitas utilizarlo en un proceso batch (dentro de un .bat, vamos), puedes ejecutarlo con la opción /b (sirve también -b o --b) y no mostrará el encabezado informativo ni tampoco se detendrá, por lo que tendrás únicamente como salida a la consola las versiones disponibles:

dotnetversions --b

Puedes ver un mini-ayuda usando el modificador -? (o -help, y vale con / o con doble guión --).

Puedes ver el código fuente en GitHub y descargar un ZIP con el ejecutable listo para utilizar.

¡Espero que te resulte útil!

Lenguaje C#: interfaces y qué diferencia existe entre implementarlas explícita o implícitamente

09/10/2019
Artículo original

Piezas de lego, foto por Nathan Duck en Unsplash, CC0

Las interfaces son una abstracción estupenda que nos ofrecen la mayor parte de los lenguajes de programación orientados a objetos. Básicamente nos permiten definir un "contrato" sobre el que podemos estar seguros de que, las clases que las implementen, lo van a cumplir.

Por ejemplo, podemos definir una interfaz muy simple de esta manera que nos servirá para crear clases que representen a animales que vuelan:

public interface IVolador
{
    void Volar();
}

De este modo estamos diciendo que si una clase la implementa tiene necesariamente que tener un método llamado Volar con la firma del que hemos puesto ahí, es decir, que no devolverá nada ni tomará parámetro alguno. Internamente cada clase lo implementará de una forma diferente.

Así, por ejemplo, podemos definir una clase Aguila y otra Abeja que implementen esta interfaz. En ambos casos el "bicho" volará, pero lo hará de forma diferente. Si fuese un juego, por ejemplo, el águila movería las alas despacio y se desplazaría a toda velocidad, mientras que la abeja las movería muy rápido y se trasladaría de manera errática en distancias cortas.

Cuando la aplicamos a la definición de una clase tenemos dos maneras de implementar una interfaz: de manera explícita o de manera implícita. De hecho, el propio Visual Studio nos ofrece ambas posibilidades en cuanto la añadimos a la clase:

Animación que muestra el diálogo de error de VS y las correcciones propuestas

Así, si por ejemplo quisiésemos implementar la interfaz en la clase Abeja, la manera explícita sería esta:

public class Abeja : Animal, IVolador
{
    //Miembros propios de la clase Abeja
    //....
    //

    //Implementación explícita de la interfaz
    IVolador.Volar()
    {
        //Código que haga lo que sea para esta clase en particular
    }
}

La forma implícita de implementarla es muy similar:

public class Abeja : Animal, IVolador
{
    //Miembros propios de la clase Abeja
    //....
    //

    //Implementación implícita de la interfaz
    public Volar()
    {
        //Código que haga lo que sea para esta clase en particular
    }
}

El código es el mismo en ambos casos. Las únicas diferencias son dos:

  1. En el caso de la implementación explícita es necesario indicar el nombre de la interfaz delante del nombre del método: IVolador.Volar(), precisamente de ahí viene el nombre, puesto que estamos indicando explícitamente que ese método es el que cumple el contrato establecido por la interfaz.
  2. En el caso de la implementación implícita necesitamos indicar que el método es público, ya que si se cumple la interfaz, éste debe ser accesible desde el exterior de la clase con el mismo nivel de acceso que la propia clase. Fíjate que en el primer fragmento no se indica nada.

Pero en ambos casos el resultado es el mismo: la interfaz queda implementada y el método Volar funcionará igual en ambos casos.

Entonces ¿por qué existen dos maneras de hacer lo mismo?

En realidad sí que existe una gran diferencia entre una forma y la otra de hacer lo mismo, solo que no nos daremos cuenta hasta que lo necesitemos. La diferencia estriba en que si definimos la interfaz explícitamente, solo podremos acceder a la funcionalidad de dicha interfaz cuando la estemos tratando como un objeto de dicha interfaz.

En el ejemplo anterior, mira qué nos enseña el compilador si intentamos este código:

Abeja maya = new Abeja();
maya.Volar();

Error de método no encontrado por parte del compilador

Fíjate en cómo, a pesar de que el método existe y está implementado en la clase, el compilador nos dice que no existe ningún método Volar y que deberíamos implementarlo. WTF?

El motivo es, como decía antes, que cuando implementamos una interfaz de manera explícita solo se va a ver si usamos el objeto conformado con esa interfaz. Esto implica hacer una conversión (o cast), o bien usar el operador as. O sea, así:

Abeja maya = new Abeja();
IVolador mayavoladora = maya as IVolador;
mayavoladora.Volar();

En donde utilizamos el operador as para conformar la variable maya a la interfaz IVolador, o bien así:

Abeja maya = new Abeja();
((IVolador)maya).Volar();

que utilizamos una conversión explícita (el (IVolador) delante de la variable) para conformar la variable maya a la interfaz que nos interesa. Ambas formas son equivalentes.

Sin embargo, cuando la implementamos de manera implícita, es un miembro normal de la clase, por lo que podemos usarla directamente y no tenemos que complicarnos.

Pero entonces ¿por qué iba a querer alguien implementar una interfaz de manera explícita?

La respuesta es que el uso explícito nos proporciona una mayor seguridad de tipos y un mayor orden.

Por ejemplo, ¿qué pasa si tenemos dos interfaces que se pueden implementar en un momento dado sobre la misma clase y que tienen un miembro en común?

En nuestro ejemplo sencillo con los animales podríamos necesitar implementar una interfaz IPajaro con varios métodos y propiedades específicos, y entre ellos un método Volar(). A los pájaros los marcamos con esta interfaz, pero a todos los bichos que vuelan los marcamos con la interfaz IVolador para poder hacer algo específico con ellos o poder localizarlos más fácilmente en ciertas colecciones.

Fíjate en cómo cambia el resultado del compilador cuando cambiamos la implementación explícita por la implícita en esta animación:

Amimación, explicada a continuación

En la animación se ve cómo, de entrada, al estar implemementado tan solo el método Volar() para la interfaz IVolador, el compilador se queja de que IPajaro no está completamente implementado (claro, le falta su propio método Volar()). Tenemos dos soluciones:

  • Implementar explícitamente IPajaro.Volar() (podríamos reutilizar el código de la anterior, no hace falta copiar y pegar)
  • Dejar la implementación implícita, como se ve en la animación, en la que no especificamos interfaz alguna delante de Volar().

En este último caso el método público Volar() sirve para todos los casos: para cuando usemos la clase directamente, para cuando se use como IVolador y como IPajaro.

Esto puede parecer que es lo que queremos siempre, pero dependiendo de nuestra aplicación puede que tengamos necesidad de que un método se comporte de manera diferente según la interfaz a través de la cual se esté utilizando, y que además no se pueda usar en otras circunstancias. En este caso hay que implementarlo de manera específica y distinta según la interfaz.

Por ejemplo, siguiendo con nuestros animalitos, supongamos que tenemos otras dos interfaces para implementar animales terrestres (ITerrestre) y animales acuáticos (IAcuatico), además de los voladores que ya hemos visto. Un perro es terrestre y un pez es acuático pero, si pensamos en las ranas, se trata de animales anfibios que van tanto por agua como tierra. Así que una rana implementaría las dos interfaces: ITerrestre y IAcuatico. Cuando lo estemos usando como animal terrestre solo podrá Caminar(), y como animal acuático solo podrá Nadar(), pero mientras nada no camina y viceversa. Es decir, en este caso aunque no hay coincidencia de interfaces, sí que deberíamos implementarlas de manera explícita. No queremos que en un contexto cualquiera se pueda llamar a Nadar() o Caminar() puesto que a lo mejor no es correcto. Así que hay que llamar en cada caso a lo que corresponda.

¡Espero que te resulte útil!

CVE-2019-15845: Una vulnerabilidad de inyección de NUL en File.fnmatch y File.fnmatch?

06/10/2019
Artículo original

Se encontró una vulnerabilidad de inyección de NUL en metodos incluidos en Ruby (File.fnmatch y File.fnmatch?). Un atacante que controle el parametro con el patrón de ruta podría explotar esta vulnerabilidad para hacer que pase el reconocimiento de algunas rutas no deseadas por el autor del programa. CVE-2019-15845 se ha asignado a esta vulnerabilidad.

Detalles

Los métodos incluidos File.fnmatch y su alias File.fnmatch? aceptan el patrón de ruta como primer parámetro. Cuando el patrón contiene el caracter NUL (\0), los métodos reconocen que el patrón de ruta termina inmediatamente antes del byte NUL. Por esto, con un programa que use una entrada externa como argumento para el patrón, un atacante podría hacerlo reconocer erradamente una ruta que es el segundo parámetro.

Todos los usuarios que corran una versión afectada deberían actualizar tan pronto como sea posible.

Versiones afectadas

  • Todas las versiones que son de la serie 2.3 y anteriores.
  • Serie Ruby 2.4: Ruby 2.4.7 o anterior
  • Serie Ruby 2.5: Ruby 2.5.6 o anterior
  • Serire Ruby 2.6: Ruby 2.6.4 o anterior
  • Ruby 2.7.0-preview1
  • rama master antes de la contribución a0a2640b398cffd351f87d3f6243103add66575b

Agradecimientos

Gracias a ooooooo_q por descrubir este problema.

Historia

  • Publicado originalmente en ingles el 2019-10-01 11:00:00 (UTC)

Publicado por mame el 2019-10-01
Traducción de vtamara

CVE-2019-16255: Una vulnerabilidad de inyeccion de código en Shell#[] y Shell#test

06/10/2019
Artículo original

Se encontró una vulnerabilidad de inyección de código en Shell#[] y Shell#test en están en la librería estándar (lib/shell.rb). A la vulnerabilidad se le ha asignado el identificador :CVE CVE-2019-16255.

Detalles

Shell#[] y su alías Shell#test que se definene en lib/shell.rb permiten inyectar código si el primer argumento (tambień conocido como el argumento con la “orden”) es un dato no confiable. Un atacante puede explotar esto para llamar un método Ruby arbitrario.

Note que pasar datos no confiables a métodos de Shell es en general peligroso. Los usuarios nunca deberían hacerlo. Sin embargo tratamos este caso particular como una vulnerabilidad porque el propósito de Shell#[] y Shell#test se considera comprobar la existencia de un archivo.

Todos los usuarios que corran una versión afectada deben actualizar de inmediato.

Versiones afectadas

  • Tdoas las versiones que son Ruby 2.3 o anteriores
  • Serie Ruby 2.4: Ruby 2.4.7 o anterior
  • Serie Ruby 2.5: Ruby 2.5.6 o anterior
  • Serie Ruby 2.6: Ruby 2.6.4 o anterior
  • Ruby 2.7.0-preview1

Agradecimientos

Gracias a ooooooo_q por descubrir este problema.

Historia

  • Original publicado el 2019-10-01 11:00:00 (UTC)

Publicado por mame el 2019-10-01
Traducción de vtamara

CVE-2019-16254: Separación de respuesta HTTP en WEBrick (Corrección adicional)

06/10/2019
Artículo original

Hay una vulnerabilidad de separación de respuesta HTTP en el WEBrick incluido con Ruby. A esta vulnerabilidad se le ha asignado el identificador CVE CVE-2019-16254.

Detalles

Si un programa que use WEBrick inserta datos de entrada con confiables en las cabeceras de la respuesta HTTP, un atacante puede explotarlo para inserta un caracter de nueva línea para dividir el encabezado, e insertar contenido maliciosos que engañe a los clientes.

Este es el mismo incidente CVE-2017-17742. La corrección anterior estaba incompleta, porque tenía en cuenta el vector CRLF, pero no tenía en cuenta un CR aislado o un LF aislado.

Todos los usuarios que ejecuten una versión afectada debe actualizar de inmediato.

Versiones afectadas

  • Todas las versiones de la serie Ruby 2.3 o anteriores
  • Serie Ruby 2.4: Ruby 2.4.7 o anterior
  • Serie Ruby 2.5: Ruby 2.5.6 o anterior
  • Serie Ruby 2.6: Ruby 2.6.4 o anterior
  • Ruby 2.7.0-preview1
  • Rama master antes de la contribución 3ce238b5f9795581eb84114dcfbdf4aa086bfecc

Agradecimientos

Gracias a znz por descubrir el problema.

Historia

  • Publicado en inglés originalmente el 2019-10-01 11:00:00 (UTC)

Publicado por mame el 2019-10-01
Traducción de vtamara

Telefónica abrirá centros 42 en Barcelona, Málaga, Valencia y Vizcaya, para aprender programación gratis y sin experiencia previa

26/09/2019
Artículo original

Telefónica abrirá centros 42 en Barcelona, Málaga, Valencia y Vizcaya, para aprender programación gratis y sin experiencia previa

En junio conocimos el proyecto de campus 42 Madrid, un concepto de escuela de programación pionero en España, 100% gratuita, colaborativa, disponible todo el año las 24 horas del día, y a la que cualquier persona mayor de 18 años puede inscribirse sin conocimientos previos ni preparación.

Hoy, durante la inauguración del campus, José María Álvarez-Pallete, presidente de Telefónica, ha anunciado que en el próximo año y medio, la Fundación Telefónica abrirá cuatro nuevos campus. Se abrirán en Barcelona, Málaga, Valencia y Vizcaya. Se sumarán así al de Madrid y a uno que Telefónica ha abierto en São Paulo.

Según la Fundación Telefónica, esta primera edición ha sido todo un éxito desde el punto de vista de las inscripciones, pues han recibido más de 17.000 solicitudes. De esas, 36% proceden de mujeres y el 64% procede de hombres. El 45% procede de personas que viven en Madrid y el 55% restante de personas de otras provincias e incluso otros países.

42 Madrid se abre oficialmente en noviembre, pero ya está funcionando

42 Madrid

42 Madrid está operativo desde septiembre, tal y como la compañía anunció que ocurriría en junio. De momento, eso sí, no está oficialmente abierto, pues eso pasará el cuatro de noviembre. Lo que de momento están haciendo cada día 300 aspirantes son las 'piscinas', pruebas finales y definitivas de acceso a la escuela. El curso comenzará con 300 alumnos, aunque más tarde se irá incrementando el número de plazas hasta 900.

En el campus se quiere potenciar la programación a través de un modelo colaborativo, con gamificación y peer to peer, pero Telefónica afirma que lo que se enseña también forma en resolución de problemas, pensamiento crítico, coordinación en equipo o toma de decisiones. Todo esto se promueve en espacios como Studio42, donde se puede hacer charlas, talleres y diferentes actividades. Como no falta en casi ninguna gran tecnológica, paradójicamente también hay espacios, que aquí se llaman refugios, para desconectar de todo lo digital y descansar.

El plan de estudios ofrece más de 100 proyectos y actividades, con una introducción que incluye interacciones de línea de comandos, programación en C elemental y algoritmos elementales. Después se aprenderán bases de programación, divididas en cuatro caminos a elegir entre Programación gráfica, Algorítmica, programación en C y Unix y programación Web. Después llegan las practicas iniciales, de entre 4 y 6 meses, y una vez superadas ya se ofertarán esos más de 100 proyectos, entre los que se podrá aprender, seguridad web, ingeniería inversa, inteligencia artificial, programación avanzada de Unix o en 3D, programación web, móvil, funcional, de redes, orientada a objetos, etc.

Según Telefónica, con la metodología de gamificación que ya se ha llevado a cabo en otros países, la inserción laboral es del 100%, con ocho ofertas de empleo de media por cada alumno durante el paso por la escuela. Aunque puedes ir a tu ritmo, el aprendizaje es 100% presencial y dura 3,5 años.

Página Siguiente