Early Return or guard clauses blog post by Felipe Elia.

Melhore seu código com Early Return

Para mim, early return (“retorno precoce”, talvez?) é a técnica mais simples e rápida para melhorar a legibilidade do seu código em 300%. Foi algo que eu aprendi colaborando com o WordPress e que compartilho com todo mundo sempre que posso.

A técnica, também chamada de guard clauses, consiste em sair da função o mais rápido possível, se alguma condição essencial não for satisfeita. A melhoria mais perceptível é a remoção de ifs aninhados. Vamos pro código que vai ficar mais fácil de entender.

Imagine uma função de WordPress que faz mudanças na busca, mas somente se algumas condições forem satisfeitas:

PHP
function felipeelia_change_search( $query ) {
	if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
		$current_site = get_current_blog_id();

		if ( 1 === $current_site ) {
			$search_term = $query->get( 's' );

			if ( strtolower( $search_term ) === 'super special search' ) {
				$post_type = $query->get( 'post_type' );

				if ( empty( $post_type ) ) {
				    // Somente neste if estamos realmente fazendo alguma coisa.
					$query->set( 'posts_per_page', '1' );

					$tax_query = [
						[
							'taxonomy' => 'category',
							'field'    => 'slug',
							'terms'    => 'news',
						],
					];
					$query->set( 'tax_query', $tax_query );

					$query->set( 'order', 'asc' );
				}
			}
		}
	}
}
add_action( 'pre_get_posts', 'felipeelia_change_search' );

Agora a versão com early returns ou guard clauses:

PHP
function felipeelia_change_search_early_return( $query ) {
	if ( is_admin() || ! $query->is_main_query() || ! $query->is_search() ) {
		return;
	}

	$current_site = get_current_blog_id();
	if ( 1 !== $current_site ) {
		return;
	}

	$search_term = $query->get( 's' );
	if ( strtolower( $search_term ) !== 'super special search' ) {
		return;
	}

	$post_type = $query->get( 'post_type' );
	if ( ! empty( $post_type ) ) {
		return;
	}

	$query->set( 'posts_per_page', '1' );

	$tax_query = [
		[
			'taxonomy' => 'category',
			'field'    => 'slug',
			'terms'    => 'news',
		],
	];
	$query->set( 'tax_query', $tax_query );

	$query->set( 'order', 'asc' );
}
add_action( 'pre_get_posts', 'felipeelia_change_search_early_return' );

Repare que, embora a segunda versão seja um pouco maior, a sequência de ifs e returns ajudam a escanear o código. Além disso, o que a nossa função realmente faz de importante está só com uma indentação, ao invés de cinco!

Exemplo da vida real: early return no ElasticPress

Agora um outro exemplo, dessa vez do plugin ElasticPress. Veja como o método Facets::is_facetable() seria sem early returns:

PHP
public function is_facetable( $query ) {
	if ( ! \apply_filters( 'ep_is_facetable', false, $query ) ) {
		if ( ! is_admin() && ! is_feed() ) {
			if ( ! defined( 'WP_CLI' ) && ! WP_CLI ) {
				if ( $query->is_main_query() ) {
					$ep_integrate = $query->get( 'ep_integrate', null );

					if ( false !== $ep_integrate ) {
						$woocommerce = Features::factory()->get_registered_feature( 'woocommerce' );

						if ( $woocommerce->is_active() && function_exists( 'is_product_category' ) && is_product_category() ) {
							if ( $this->is_facetable_page( $query ) ) {
								return true;
							}						
						}
					}
				}
			}
		}	
	}
	return false;
}

Agora a versão real do método:

PHP
public function is_facetable( $query ) {
	if ( \apply_filters( 'ep_is_facetable', false, $query ) ) {
		return true;
	}

	if ( is_admin() || is_feed() ) {
		return false;
	}

	if ( defined( 'WP_CLI' ) && WP_CLI ) {
		return false;
	}

	if ( ! $query->is_main_query() ) {
		return false;
	}

	$ep_integrate = $query->get( 'ep_integrate', null );
	if ( false === $ep_integrate ) {
		return false;
	}

	$woocommerce = Features::factory()->get_registered_feature( 'woocommerce' );
	if ( ! $woocommerce->is_active() && ( function_exists( 'is_product_category' ) && is_product_category() ) ) {
		return false;
	}

	if ( ! $this->is_facetable_page( $query ) ) {
		return false;
	}

	return true;
}

Muito melhor, não é?

Não existe bala de prata

Early returns ou guard clauses são ótimos, mas não são a solução para tudo. Se o seu código tem vários else, por exemplo, considere quebrar a função em funções menores ou então você terá returns espalhados por todo o código, o que acaba dificultando o entendimento.

Se você gostou do post não se esqueça de compartilhar!

Deixe um comentário

Este site é protegido por reCAPTCHA e pelo Googlepolítica de Privacidade eTermos de serviço aplicar.