martes, 27 de marzo de 2018

Todas las abstracciones fugan

Esta frase la he escuchado (y leído) bastantes veces, y para ser honesto, nunca terminé de entender a que se refería. Hace poco volví a leerla y me dije: Entendámosla de una vez por todas
¿De donde viene todo? Del artículo The law of leaky abstractions, escrito en Noviembre de 2002 por Joel Spolsky.

“All non-trivial abstractions, to some degree, are leaky”

Viene a decir que toda abstracción, excluyendo aquellas que son triviales, tarde un temprano fuga, revelando aspectos que tratábamos de abstraer.

Veámoslo con un ejemplo:


Todos hemos visto una implementación del patrón repository como la siguiente:

    public interface IStudentRepository : IDisposable
    {
        IQueryable<Student> GetStudents();
        Student GetStudentByID(int studentId);
        void InsertStudent(Student student);
        void DeleteStudent(int studentID);
        void UpdateStudent(Student student);
        void Save();
    }

El hecho de que el método GetStudents devuelva un IQueryable implica que debamos conocer detalles acerca de la implementación del repositorio, conocer que hay detrás, ya que el proveedor de Linq ejecutará algunas instrucciones en memoria y otras sobre una motor de bases de datos. No podemos ignorarlo si queremos no meternos en líos. Podemos decir por tanto que nuestra abstracción IStudentRepository fuga


¿Hay más ejemplos comunes?


Por supuesto, una rápida búsqueda por internet nos dará un bonito listado de abstracciones, que usamos comúnmente, y que fugan (¿todas lo hacen no? XDXD)
  • El garbage collector: tarde o temprano, si tu aplicación realiza mucha presión sobre la memoria, o si es una aplicación que necesita un altísimo rendimiento, tendrás que entender su implementación para alcanzar ese nivel de optimización deseado.
  • Un sistema de ficheros distribuido, bajo SMB por ejemplo, trata de abstraerte de que los ficheros están en remoto, mostrándolos como si de un disco local se tratase.  No obstante la latencia o los posibles micro-cortes de red pueden hacer que tengas que manejar dichos ficheros de un modo diferente (y conocer que de hecho esos ficheros no son locales).
  • La clase string de C# por ejemplo, que debido su implementación genera un nuevo string cada vez que concatenamos dos strings existentes previamente. Si no conocemos este detalle, podemos sufrir serios problemas de rendimiento y escalabilidad.

¿Es esto malo?


No lo considero necesariamente malo, simplemente está ahí y lo mejor es que lo conozcamos y seamos conscientes de ello.
Nuevas tecnologías y herramientas tratan de elevar el nivel de abstracción que manejamos al desarrollar software, nos obstante, ya que estas abstracciones fugarán de un modo u otro, debemos conocer sus detalles, cómo estas abstracciones funcionan y han sido implementadas, antes de pasar sin más a utilizarlas.

Recursos: 


2 comentarios:

  1. Que raro que C# haga eso con los strings. En Java el compilador sustituye las concatenaciones por llamadas a StringBuilder para evitar crear nuevos strings.

    ResponderEliminar
    Respuestas
    1. Pues salvo que lo hayan cambiado recientemente, en c# tienes q usar explícitamente el StringBuilder si no quieres el efecto "concatenación", o bien usar interpolación.

      Aquí hay datos de performance: https://dotnetcoretutorials.com/2020/02/06/performance-of-string-concatenation-in-c/

      Tengo que mirar q pasa en .net 5 que acaba de salir del horno

      Eliminar