Hoy no vamos a hablaros sobre técnicas para mejorar vuestro código a nivel técnico, tenemos artículos sobre SOLID y patrones de diseño para eso. Hoy vamos a hablaros de la regla del boy scout.
Puede que a muchos no os suene ese concepto, pero va muy ligado a las buenas prácticas en programación, autores como Robert C. Martin o Martin Fowler hablan de esta regla en varios de sus libros.
¿Qué es la regla del boy scout?
Pero, ¿qué es la regla del boy scout? ¿de dónde viene su nombre? ¿En que me afecta como desarrollador de software?
Vamos a hacer una pequeña introducción para ponernos en situación, pongamos un ejemplo de código.
void Resize()
{
Canvas.ForceUpdateCanvases();
KeyboardInput largestInput = _inputsB2[0];
for (int i = 0; i < _inputsB2.Count; i++)
if (_inputsB2[i].GetWesternmostLocalPosition() < largestInput.GetWesternmostLocalPosition())
largestInput = _inputsB2[i];
//width
_b2.OnInputModified(largestInput);
//Bloc2 high and psition square
_b2.Rt.sizeDelta = new Vector3(_b2.Rt.sizeDelta.x, _inputsB2.Count <= 2 ?
(_inputsB2[0].Tmp.fontSize * 0.3f + _inputsB2[0].Tmp.fontSize * _inputsB2.Count) :
(_inputsB2[0].Tmp.fontSize * _inputsB2.Count));
_b2.Rt.localPosition = new Vector3(_b2.Rt.localPosition.x, _separator1.localPosition.y -
_separator1.sizeDelta.y - _b2.Rt.sizeDelta.y / 2 - 5);
//_b2.Rt.localPosition = new Vector3(35.3f, _separator1.localPosition.y - _separator1.sizeDelta.y
- _b2.Rt.sizeDelta.y / 3 - 2);
//RePosition all fields B2
_inputsB2[0].transform.position = new Vector3(_inputsB2[0].transform.position.x,
transform.TransformPoint(_separator1.localPosition - new Vector3(0, 50)).y);
for (int i = 1; i < _inputsB2.Count; i++)
_inputsB2[i].Rt.localPosition = new Vector3(_inputsB2[i].Rt.localPosition.x,
_inputsB2[0].Rt.anchoredPosition.y - i * _inputsB2[0].Rt.sizeDelta.y);
if (Bloc3 != null)
ResizeBloc3();
}
Este código es parte de una clase con más de 2000 lineas, más de lo aconsejable si seguimos los principios SOLID. Tiene nombres de variables poco descriptivas, código comentado, demasiadas responsabilidades, etc. Ya lo hemos visto más veces.
Vale, ¿y qué tiene que ver con los boy scouts? YA VAMOS!!
Sobre los Boy Scouts
Los boy scout como todos, o casi todos sabréis, son una asociación juvenil creada en 1910 en EEUU. Básicamente son grupos de niños, creo que se puede ingresar a partir de los 7 años, que acompañados de monitores hacen excursiones los fines de semana y así conocer la naturaleza de las localidades cercanas a donde viven.
Una de las actividades más conocidas que realizan es la de montar campamentos para pasar la noche al aire libre mientras cuentan historias de miedo y se enciende un fuego para hacer algo de comida y pasar mejor la noche.
Nunca he formado parte de una asociación de este tipo, pero debe ser una actividad muy enriquecedora.
El caso es que como todo, hay un momento en el que toca recoger, y una de las principales normas de los boy scouts es «deja el campamento más limpio de como te lo encontraste».
Su significado asociado a la acampada está claro, divierte en la naturaleza y adáptala a tus necesidades, pero cuando te vayas deja las cosas mejor de como estaban.

¿Y esto qué tiene que ver con el desarrollo de software?
Muchos de vosotros ya lo debéis intuir, pero ¿qué relación tiene esto con las buenas prácticas en programación?, pues justo eso, muy a menudo nos encontramos código como el que teníamos arriba. Lo «fácil» es llegar a ese escenario, entender cómo funciona el código tras releerlo varias veces e introducir nuestra funcionalidad por ahí en medio.
Todos sabemos que ese código necesita ser refactorizado, cambiado o quizás destruido pero es evidente que, probablemente, nos lleve más tiempo realizar esos cambios que introducir la funcionalidad que debemos programar y salir de ahí cuanto antes.
Pero igual no hace falta llevar hasta ese grado de profundidad el arreglo de esa clase. Simplemente el coger partes del código que nos han resultado difíciles de entender y sacarlo a funciones pequeñas que expliquen qué hacen en el propio nombre de la función, poner nombres significativos a las variables que vamos a tocar, cambiar números mágicos por constantes, quizás sacar un switch a una factory, o crear un builder.
Aplicando la regla del boy scout al código
Continuando con el ejemplo del principio vamos a ver cómo podemos aplicar la regla del boy scout en un caso real.
Podemos empezar con lo más obvio, quitar el código comentado, el código comentado no debería llegar a producción, así que si en algún momento se nos pasó, ahora es momento de hacerlo desaparecer.
Lo siguiente puede ser pasar a funciones con un nombre descriptivo los bloques de código que tienen comentarios justo encima. Esto nos lo puede realizar nuestro IDE (Rider en nuestro caso), minimizando así los posibles errores.
Vamos a verlo paso a paso:
Vamos a setear el ancho
...
//width
_b2.OnInputModified(largestInput);
...
Quedaría de la siguiente manera
private void SetWidth(SquareKeyboardInput largestInput)
{
_b2.OnInputModified(largestInput);
}
Ahora setearemos la altura y la posición:
...
//Bloc2 high and psition square
_b2.Rt.sizeDelta = new Vector3(_b2.Rt.sizeDelta.x, _inputsB2.Count <= 2 ?
(_inputsB2[0].Tmp.fontSize * 0.3f + _inputsB2[0].Tmp.fontSize * _inputsB2.Count) :
(_inputsB2[0].Tmp.fontSize * _inputsB2.Count));
_b2.Rt.localPosition = new Vector3(_b2.Rt.localPosition.x, _separator1.localPosition.y -
_separator1.sizeDelta.y - _b2.Rt.sizeDelta.y / 2 - 5);
//_b2.Rt.localPosition = new Vector3(35.3f, _separator1.localPosition.y - _separator1.sizeDelta.y
- _b2.Rt.sizeDelta.y / 3 - 2);
...
Crearemos una función para ello
private void SetHeighAndPosition()
{
_b2.Rt.sizeDelta = new Vector3(_b2.Rt.sizeDelta.x, _inputsB2.Count <= 2 ?
(_inputsB2[0].Tmp.fontSize * 0.3f + _inputsB2[0].Tmp.fontSize * _inputsB2.Count) :
(_inputsB2[0].Tmp.fontSize * _inputsB2.Count));
_b2.Rt.localPosition = new Vector3(_b2.Rt.localPosition.x, _separator1.localPosition.y -
_separator1.sizeDelta.y - _b2.Rt.sizeDelta.y / 2 - 5);
}
Posicionamos los campos necesarios
//RePosition all fields B2
_inputsB2[0].transform.position = new Vector3(_inputsB2[0].transform.position.x,
transform.TransformPoint(_separator1.localPosition - new Vector3(0, 50)).y);
for (int i = 1; i < _inputsB2.Count; i++)
_inputsB2[i].Rt.localPosition = new Vector3(_inputsB2[i].Rt.localPosition.x,
_inputsB2[0].Rt.anchoredPosition.y - i * _inputsB2[0].Rt.sizeDelta.y);
Lo pasamos a nuestro nuevo método
private void RepositionAllFields()
{
_inputsB2[0].transform.position = new Vector3(_inputsB2[0].transform.position.x,
transform.TransformPoint(_separator1.localPosition - new Vector3(0, 50)).y);
for (int i = 1; i < _inputsB2.Count; i++)
_inputsB2[i].Rt.localPosition = new Vector3(_inputsB2[i].Rt.localPosition.x,
_inputsB2[0].Rt.anchoredPosition.y - i * _inputsB2[0].Rt.sizeDelta.y);
}
Por último el bloque de código final.
if (Bloc3 != null)
ResizeBloc3();
Se puede sacar a un método y llamarlo desde la función que llama a nuestra Resize()
y que realice sus funciones en ese momento sin darle esa responsabilidad a nuestro método.
El resultado final sería el siguiente:
void Resize()
{
Canvas.ForceUpdateCanvases();
KeyboardInput largestInput = _inputsB2[0];
for (int i = 0; i < _inputsB2.Count; i++)
if (_inputsB2[i].GetWesternmostLocalPosition() < largestInput.GetWesternmostLocalPosition())
largestInput = _inputsB2[i];
SetWidth(largestInput);
SetHeighAndPosition();
RepositionAllFields();
}
Como vemos nuestro método Resize()
ha quedado mucho más legible. No hemos entrado en cómo se leen las funciones que hemos sacado, ni es un refactor que entrañe riesgo de introducir un bug ante la falta de test.
Estos pequeños arreglos no nos desviarán de la previsión que tengamos a la hora de hacer nuestra tarea. Hemos tardado solo un par de minutos en realizarlos.
Estos pequeños cambios han sido suficientes para cumplir con nuestra regla del boy scout, hemos dejado más limpio nuestro código una vez hemos implementado nuestra nueva funcionalidad.
Conclusión
Hemos mejorado el código de nuestra aplicación de una forma rápida y sin introducir errores. No nos hemos desviado en nuestra estimación de tiempo, nos ha llevado solo un par de minutos.
Los cambios que hemos hecho nos ayudarán a nosotros mismos cuando nos toque volver a revisar esa parte del código, o al siguiente compañero que se adentre ahí.
Si esta práctica, la regla del boy scout, se extiende por todo o parte del equipo de programación, a medio plazo tendremos arreglada esa clase sin que haya significado el parar la producción de nuevas características en el producto.
Así que ya sabes… la próxima vez que te encuentres un código de ese tipo, piensa en los boy scouts, piensa en ti volviendo a visitar ese desastre tal y como está y deja el código un poco más limpio de cómo lo encontraste, a medio plazo tu y el mundo de la programación te lo agradecerá. Seguro.
Y, como siempre, más abajo tenéis un espacio donde cualquier duda o comentario siempre será bien recibida.
Recuerda que aquí tenemos un curso sobre SOLID y Clean Code en el que tratamos este y otros temas que te ayudarán a escribir mejor código.
Fuentes
- Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin)
- Refactoring: Improving the Design of Existing Code (Martin Fowler)
Otros posts
- Patrones de diseño – State pattern
- Unity Addressables, ¿vale la pena?
- Patrones de diseño – Command
- Cómo los principios SOLID y Clean Code pueden acelerar la producción de tu juego: consejos y ejemplos
- Unity y los Assembly Definitions
- Los 5 errores más habituales en el desarrollo de videojuegos y su resolución con SOLID y Clean Code


La regla del boy scout está bien pero el enfoque se puede mejorar, ya que puedes encontrarte ésta situación en diferentes escenarios.
En primer lugar un código así no debería pasar una PR, pero los desarrolladores tenemos unas deadlines muy justas y miramos las PRs en diagonal.
Llegados a ésta situación si el refactor no implica grandes cambios podría permitirse en la misma PR que la tarea.
Sin embargo, en muchas ocasiones esto desvía la atención / el foco de la PR. Siempre es mejor algo pequeño y fácil de revisar con un mismo contexto por muy pequeño que sea.
Primero de todo, muchas gracias por tu aportación y 100% de acuerdo con la observación, idealmente ese código no debería llegar a producción.
Ahora bien, no todos los proyectos tienen miembros con experiencia suficiente al inicio de su desarrollo y código similar acaba estando en producción. Ahí es cuando un miembro con suficiente experiencia y sin invertir mucho tiempo puede aplicar esta regla del boy scout para mejorar el código.
Por otra parte hacer un refactor dentro de la PR de otra tarea puede estar fuera del scope de dicha tarea (dependiendo de las normas de code review de cada equipo) y por lo tanto no llegar a plantearse nunca ese cambio.
De ahí la importancia de interiorizar esta regla, debería ser una pauta de comportamiento a la hora de desarrollar y no una reacción a una revisión.
Los comentarios están cerrados.