A lo largo de la vida de cualquier código que escribimos, este va a ser leído muchas más veces que escrito o modificado. Esto conlleva que es importante que el código que escribimos sea lo más legible posible. Si es fácil de leer, en las multiples veces que será leído posteriormente se ahorrará un tiempo muy valioso para las personas que lo leen o incluso para nosotros mismos en el futuro.
Como dice Martín Fowler:
Any fool can write code that a computer can understand. Good programmers write code that humans can understand
Por eso debemos escribir código legible para que sea entendido por tus compañeros como primer objetivo y no por el compilador.
Código poco legible
Un ejemplo de código típico que esta escrito más para máquinas que para humanos es el código que generan las plantillas de los IDEs. He seleccionado un código que crea Android Studio cuando añades una activity de tipo Master/Detail. Veamos el código que genera la plantilla para el activity de detalle.
public class ExampleDetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own detail action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState == null) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID,
getIntent().getStringExtra(ItemDetailFragment.ARG_ITEM_ID));
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container, fragment)
.commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
navigateUpTo(new Intent(this, ItemListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
Este tipo de código se lee mal, por ejemplo una persona que está empezando con Android es fácil que le cueste leerlo y entenderlo.
Código legible
Ahora vamos a ver el mismo código pero refactorizado para que sea un código legible. Cada parte con diferente valor semántico queda separada en métodos donde por el nombre, queda más claro lo que se esta haciendo. Una persona que no conoce Android le va a resultar más fácil leer este código.
public class ItemDetailActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
initializeToolbar();
initializeFloatingActionButton();
showUpButtonInActionBar();
if (savedInstanceState == null) {
showDetailFragment();
}
}
private void showDetailFragment() {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID,
getIntent().getStringExtra(ItemDetailFragment.ARG_ITEM_ID));
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.item_detail_container, fragment)
.commit();
}
private void showUpButtonInActionBar() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
private void initializeFloatingActionButton() {
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own detail action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
private void initializeToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
setSupportActionBar(toolbar);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
supportFinishAfterTransition();
return true;
}
return super.onOptionsItemSelected(item);
}
}
Consejos
Ahora voy a enumerar una serie de consejos que hacen que tu código sea más legible:
-
Los métodos tienen que ser pequeños, un método grande es más difícil de leer.
-
Cada método tiene que tener una única responsabilidad, es relacionado con el punto anterior. Si el método solo tiene una responsabilidad sera más corto y fácil de entender lo que hace.
-
Evita códigos anidados dentro de cada método, manejar errores dentro del mismo método que tiene la lógica, tener bucles anidados, son ejemplos de código anidado que complica la legibilidad. Separar estos códigos anidados en su propio método mejora la legibilidad.
En mi antiguo blog escribí un ejemplo sobre este caso.
Conclusiones
Es muy importante escribir código legible para que cualquier persona sin conocer los detalles del código sea capaz de leer y seguir el flujo.
En definitiva, escribe código legible para humanos no para máquinas.