Si nos dedicásemos a enroscar tapones de botellas probablemente podríamos medir nuestra productividad en términos del número de botellas cerradas por hora. Si cargásemos sacos en un muelle, quizás en kilos transportados por jornada... Hay muchos trabajos en los que es relativamente sencillo establecer una medida para conocer el grado de productividad con el que desempeñamos nuestras obligaciones.
Lamentablemente, esto no es así en la industria del software, que durante años ha ido dando tumbos, probando y descartando sucesivamente diversas métricas para intentar medir la productividad de los desarrolladores, como el cómputo de líneas de código por día, puntos función, puntos de historia o el grado de completitud de sprints, pero siempre sin éxito. En el desarrollo de software todo es demasiado etéreo: dado que no creamos ni manipulamos productos tangibles, no hay nada que poder pesar o contar, salvo las horas pegados a nuestra silla.
Sin embargo, todos tenemos una idea intuitiva de lo que es un desarrollador productivo, e incluso se ha hablado bastante de los desarrolladores 10x: programadores que son al menos diez veces más productivos que los que se encuentran en el lado opuesto del espectro. Esta idea parte de estudios científicos contrastados, y algunos destacados gurús incluso suben la apuesta llegando a estimar que determinados desarrolladores pueden producir entre diez y veintiocho veces más que sus compañeros. Casi nada.
Sin duda, un desarrollador 10x es todo un lujazo para las empresas, que lucharán para atraerlos, normalmente a base de ofrecer unas condiciones espectaculares, porque es mucho más rentable ofrecer a un desarrollador 10x el triple de sueldo que tener a diez desarrolladores para conseguir el mismo resultado.
Nuestro objetivo profesional, por tanto, debería ser dar el salto y convertirnos en uno de ellos.
Publicado por José M. Aguilar a las 12:01 a. m.
Etiquetas: 10x, bootcamp, inocentadas, productividad
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Dónde está Server.MapPath() en ASP.NET Core?
José María Aguilar - Cómo mostrar el número de usuarios conectados a una aplicación Blazor Server, en tiempo real
José María Aguilar
.NET Core / .NET
- Mejorar la legibilidad de números en tu código C# con separadores de dígitos
José Manuel Alarcón - What's next for System.Text.Json?
Layomi Akinrinade - Building a Code Analyzer for .NET
Tim Heuer - Batch.Parallel
Marc Clifton - C# in Simple Terms - Indexers
Matthew Jones - Implementing a Text Templating Language and Engine for .NET
Alexandre Mutel - Thinking With Properties: Examining Where
Cameron Presley - Implementing the page object pattern in UI tests
James Croft - Never forget a #if when multi-targeting .NET libraries or applications
Gérald Barré - Creating a game art asset pipeline in .NET
Sam Eddy - From .NET Standard to .NET 5
Immo Landwerth - How to add User-Agent header to HttpClient in .NET
Kristoffer Strube - .NET 5.0 on Google Cloud
Mete Atamel - Playing with C#9 Top-level Programs, Records and Elasticsearch.NET - Steve Gordon
Steve Gordon - The proper usages of Exceptions in C#
Patrick Smacchia - Overloading Vs. Overriding in C#
Sam Walpole - .NET 5 Source Generators - MediatR - CQRS
Tore Nestenius - C# vs. F#
Urs Enzler - C# 9 Covariant Return Types
Khalid Abuhakmeh
En Blazor, es habitual implementar la interfaz de nuestros componentes de forma declarativa, mezclando etiquetas que:
- Pueden ser HTML, y cuyo resultado irá textualmente al navegador
- Pueden ser instancias de otros componentes, por lo que al navegador irá el resultado de la renderización de éstos.
Por ejemplo, el siguiente código envía al navegador la etiqueta <h1>
y luego el resultado de renderizar el componente Blazor <MyComponent>
, en cuyo interior podrán existir a su vez otras etiquetas o componentes:
@page "/home"
<h1>Welcome!<h1>
<MyComponent />
Fijaos que, aunque es la fórmula que emplearemos en la mayoría de ocasiones, es una estructura totalmente rígida: podemos tener la total certeza de que el componente que será instanciado en la página anterior es MyComponent
, pero, ¿qué ocurre si queremos poder decidir en tiempo de ejecución qué componente instanciaremos en la página?
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- ¿Dónde están Application_Start y Application_End en ASP.NET Core?
José María Aguilar - Capturar todos los parámetros enviados a un componente Blazor
José María Aguilar
.NET Core / .NET
- Programación mínima, C# vs Python
Sergio León - Null Checking en C#
Jorge Serrano - What's new in Windows Forms runtime in .NET 5.0
Igor Velikorossov - .NET December 2020 Updates – 5.0.1
Rahul Bhandari - Rethrowing your exceptions wrong in .NET could erase your stacktrace
Niels Swimberghe - C# 9 records as strongly-typed ids
Thomas Levesque - Common Use Cases For .NET Reflection
Khalid Abuhakmeh - Cryptography Improvements in .NET 5
Tomasz Pęczek - Bring lights in Unity into the real-world using Philips Hue
Paul Marsh - New in .NET 5 - Top-level Statements
Bradley Wells - Automate a Markdown links page with Pinboard and C#
Dave Brock - Add Configuration to a .Net Core Console Application
Paul Michaels - C# in Simple Terms - Dates and Times
Matthew Jones - Using .NET and PowerPoint to generate cover images
Gérald Barré - No recompile, no redeploy, managing features flags in .NET Core, locally and with Azure
Chris Noring - Producing Packages with Source Link
Claire Novotny - Use local function attributes with C# 9
Dave Brock - The proper usages of the keyword 'static' in C#
Patrick Smacchia - Making C# More Welcoming
Matt Eland - Simplifying Multithreaded Scenarios With PostSharp Threading
Wade Gausden - C# 9 Records and Init Only Settings Without .NET 5
Brant Burnett - Dynamic Class Creation in C# - Preserving Type Safety in C# with Roslyn
José Manuel Redondo López
Ahí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)
Por si te lo perdiste...
- Retorno de referencias y referencias locales en C#
José María Aguilar - Mostrar HTML "crudo" en componentes Blazor
José María Aguilar
.NET Core / .NET
- Introducing WaveEngine 3.1 based on .NET 5
Javier Cantón Ferrero - C# In Simple Terms - String Manipulation and Cultures
Matthew Jones - Noisy logs? Improve your signal-to-noise ratio with per-request logging and sampling
Gael Fraiteur - .NET 5 Breaking Changes to the Base Class Library
Jonathan Allen - Investigating a performance issue with a regex
Gérald Barré - Should You Always Create a Nuget Package? Asking for a Friend...
Shawn Wildermuth - When C# 9.0 patterns go wrong: mechanism over intent
Ian Griffiths - .NET Core 2.1, 3.1, and .NET 5.0 updates are coming to Microsoft Update
Jamshed Damkewala - .NET 5 Breaking Changes: Historic Technologies
Jonathan Allen - C# 9 - Top-Level Statements & C# 8 - Switch Expressions
Claudio Bernasconi - Understand The .NET 5 Runtime Environment
Khalid Abuhakmeh
Una pequeña pero interesante novedad introducida en Blazor 5, es la posibilidad de escribir nuestras propias factorías de componentes, o, como les llaman en el framework, Component Activators.
El Component Activator es un objeto singleton que implementa la interfaz IComponentActivator
, cuyo único requisito es el cumplimiento del siguiente contrato:
public interface IComponentActivator
{
IComponent CreateInstance(Type componentType);
}
Como se puede intuir, Blazor invocará al activator registrado en el sistema justo en el momento en que va a instanciar un componente: se le suministra el tipo como parámetro, y retornará ya un objeto IComponent
, la interfaz más básica que cumplen todos los componentes Blazor.
Por defecto, se utiliza como activador la clase interna DefaultComponentActivator
:
internal class DefaultComponentActivator : IComponentActivator
{
public static IComponentActivator Instance { get; } = new DefaultComponentActivator();
public IComponent CreateInstance(Type componentType)
{
var instance = Activator.CreateInstance(componentType);
if (!(instance is IComponent component))
{
throw new ArgumentException($"The type {componentType.FullName}"
+ $"does not implement {nameof(IComponent)}.", nameof(componentType));
}
return component;
}
}
Obviamente, si quisiéramos intervenir en el proceso de construcción de componentes, sólo tendremos que implementar nuestra clase personalizada y registrarla como singleton en el inyector de dependencias, asociada a la interfaz IComponentActivator
.
Para crear nuestra propia implementación, fijaos que la clase DefaultComponentActivator
es interna y no podemos heredar de ella, pero tiene un código tan simple que podemos usarlo para crear nuestras propias versiones.
Veamos un par de ejemplos.