Dependendo da situação específica, os desenvolvedores médios costumam ser 10% a 20% menos eficientes do que os desenvolvedores excelentes. Bons desenvolvedores são mais eficientes porque possuem ampla experiência e bons hábitos de programação. Maus hábitos de programação afetarão a eficiência. Este artigo ajuda você a se tornar um programador melhor, demonstrando alguns bons hábitos de programação.
Esses bons hábitos de programação não apenas aumentam a eficiência, mas também permitem escrever código fácil de manter durante todo o ciclo de vida do seu aplicativo. O código que você escreve pode exigir muita manutenção. A manutenção do aplicativo é uma despesa significativa. O desenvolvimento de bons hábitos de programação pode melhorar a qualidade do design (como a modularidade), tornando o código mais fácil de entender e, portanto, mais fácil de manter, ao mesmo tempo que reduz os custos de manutenção.
Maus hábitos de programação causarão defeitos no código, dificultando sua manutenção e modificação, e provavelmente introduzirão outros defeitos durante a modificação. A seguir estão cinco bons hábitos de programação que podem ajudar o código PHP a evitar essas armadilhas:
◆Use uma boa nomenclatura.
◆Dividir em partes menores.
◆Adicione comentários ao código.
◆Lidar com condições de erro.
◆Não use copiar e colar.
Esses hábitos são detalhados abaixo:
Use uma boa nomenclatura
Usar uma boa nomenclatura é o hábito de programação mais importante porque nomes descritivos tornam o código mais fácil de ler e entender. A facilidade de compreensão do código depende de ele poder ser mantido no futuro. Mesmo que o código não esteja comentado, facilitará muito alterações futuras se for fácil de entender. O objetivo desse hábito é tornar o código que você escreve tão fácil de ler e entender quanto um livro.
Mau hábito: nomes vagos ou sem sentido
O código da Listagem 1 contém nomes de variáveis muito curtos, abreviações ilegíveis e nomes de métodos que não refletem a funcionalidade do método. Se o nome do método dá a impressão de que ele deveria fazer uma coisa, mas na verdade faz outra coisa, isso causará sérios problemas porque será enganoso.
Listagem 1. Maus hábitos: nomes vagos ou sem sentido
<?php
function getNBDay($d){
mudar($d){
caso 5:
caso 6:
caso 7:
retornar 1;
padrão:
retornar ($d + 1);
}
}
$dia = 5;
$nextDay = getNBDay($dia);
echo ("O próximo dia é: " . $nextDay . "n")
;
Boas Práticas: Nomes Descritivos e Concisos
O código da Listagem 2 demonstra boas práticas de programação. Os novos nomes dos métodos são altamente descritivos e refletem o propósito do método. Da mesma forma, os nomes das variáveis alterados são mais descritivos. A única variável que permanece mais curta é $i, que nesta listagem é uma variável de loop. Embora muitas pessoas desaprovem o uso de nomes muito curtos, é aceitável (e até benéfico) usá-los em variáveis de loop porque isso indica claramente a função do código.
Listagem 2. Boas práticas: nomes descritivos e concisos
<?php
definir('SEGUNDA-FEIRA', 1);
definir('TERÇA-FEIRA', 2);
definir('QUARTA-FEIRA', 3);
definir('QUINTA-FEIRA', 4);
definir('SEXTA-FEIRA', 5);
definir('SÁBADO', 6);
definir('DOMINGO', 7);
/*
*
* @param $diaDaSemana
* @return int Dia da semana, sendo 1 segunda-feira e assim por diante.
*/
function findNextBusinessDay($diaDaSemana){
$próximoDiaNegócio = $diaDaSemana;
switch($diaDaSemana) {
caso SEXTA-FEIRA:
caso SÁBADO:
caso DOMINGO:
$próximoDiaNegócio = SEGUNDA-FEIRA;
quebrar;
padrão:
$próximoDia Útil += 1;
quebrar;
}
return $próximoDiaBusiness;
}
$dia = SEXTA-FEIRA;
$próximoDiaBus = encontrarPróximoDiaNegócio($dia);
echo ("O dia seguinte é:" . $nextBusDay . "n");
?>
Recomendamos que você divida condições grandes em um método e, em seguida, nomeie o método com um nome que descreva a condição. Essa técnica pode melhorar a legibilidade do código e tornar a condição concreta para que possa ser extraída e até mesmo reutilizada. Também é fácil atualizar métodos se as condições mudarem. Como um método tem um nome significativo, ele reflete a finalidade do código e facilita a leitura do código.
em partes menores
antes de continuar com a programação. Se você continuar a programar enquanto resolve um problema urgente, a função se tornará cada vez mais longa. No longo prazo, isso não é um problema, mas você deve se lembrar de voltar e refatorá-lo em partes menores.
Refatorar é uma boa ideia, mas você deve adquirir o hábito de escrever códigos mais curtos e focados. Métodos curtos podem ser lidos em uma janela e são fáceis de entender. Se um método for muito longo para ser lido em uma janela, será difícil segui-lo porque você não poderá acompanhar rapidamente toda a ideia do início ao fim.
Ao construir métodos, você deve adquirir o hábito de fazer com que cada método faça apenas uma coisa. Este é um bom hábito porque: primeiro, se um método faz apenas uma coisa, então é mais provável que seja reutilizado; segundo, tal método é fácil de testar; terceiro, tal método é fácil de entender e mudar;
Mau hábito: métodos excessivamente longos (fazer muitas coisas)
A Listagem 3 mostra uma função muito longa que apresenta muitos problemas. Ele faz muitas coisas, por isso não é compacto o suficiente. Também é mais fácil de ler, depurar e testar. O que ele faz inclui iterar um arquivo, construir uma lista, atribuir valores a cada objeto, realizar cálculos e muito mais.
Listagem 3. Mau hábito: função muito longa
<?php
function writeRssFeed($user)
{
//Obtém as informações de conexão do banco de dados
// procura as preferências do usuário...
$ link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OU morrer(mysql_error());
// Consulta
$perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'",
mysql_real_escape_string($usuário));
$resultado = mysql_query($query, $link);
$max_stories = 25; // padrão para 25;
if ($linha = mysql_fetch_assoc($resultado)) {
$max_stories = $row['max_stories'];
}
//vai pegar meus dados
$perfsQuery = sprintf("SELECT * FROM histórias WHERE post_date = '%s'",
mysql_real_escape_string());
$resultado = mysql_query($query, $link);
$feed = "<versão RSS="2.0">" .
"<canal>" .
"<title>Meu ótimo feed</title>" .
"<link> http://www.example.com/feed.xml </link>" .
"<descrição>O melhor feed do mundo</descrição>" .
"<idioma>en-us</idioma>" .
"<pubDate>Ter, 20 Out 2008 10:00:00 GMT</pubDate>" .
"<lastBuildDate>Ter, 20 de outubro de 2008 10:00:00 GMT</lastBuildDate>" .
"<docs> http://www.example.com/rss </docs>" .
"<generator>Gerador MyFeed</generator>" .
"<managingEditor> [email protected] </managingEditor>" .
"<webMaster> [email protected] </webMaster>" .
"<ttl>5</ttl>";
//construir o feed...
while ($linha = mysql_fetch_assoc($resultado)) {
$título = $linha['título'];
$link = $row['link'];
$descrição = $linha['descrição'];
$data = $linha['data'];
$guid = $row['guid'];
$feed .= "<item>";
$feed .= "<título>" .
$feed .= "<link>" .
$feed .= "<descrição> " .
$feed .= "<pubDate>" .
$feed .= "<guid>" .
$feed .= "</item>";
}
$feed .= "</rss";
// escreve o feed no servidor...
echo($feed);
}
?>Se você escrever mais alguns métodos como este, a manutenção se tornará um problema real.
Bom hábito: lista de métodos gerenciáveis e específicos para funções
4 Reescreva o método original em um método mais compacto e legível. Neste exemplo, um método longo é dividido em vários métodos curtos, e cada método curto é responsável por uma coisa. Esse código é muito útil para reutilização e testes futuros.
Listagem 4. Boas práticas: abordagem fácil de gerenciar e específica de função
<?php
function createRssHeader()
{
retorne "<rss version="2.0">" .
"<canal>" .
"<title>Meu ótimo feed</title>" .
"<link> http://www.example.com/feed.xml </link>" .
"<descrição>O melhor feed do mundo</descrição>" .
"<idioma>en-us</idioma>" .
"<pubDate>Ter, 20 Out 2008 10:00:00 GMT</pubDate>" .
"<lastBuildDate>Ter, 20 de outubro de 2008 10:00:00 GMT</lastBuildDate>" .
"<docs> http://www.example.com/rss </docs>" .
"<generator>Gerador MyFeed</generator>" .
"<managingEditor> [email protected] </managingEditor>" .
"<webMaster> [email protected] </webMaster>" .
"<ttl>5</ttl>";
}
função createRssFooter()
{
return "</canal></rss>";
}
função createRssItem($título, $link, $desc, $data, $guid)
{
$item.= "<item>";
$item .= "<título>" .
$item .= "<link>" .
$item .= "<descrição> " .
$item .= "<pubDate>" .
$item .= "<guid>" .
$item.= "</item>";
retornar $item;
}
função getUserMaxStories($db_link, $default)
{
$perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'",
mysql_real_escape_string($usuário));
$resultado = mysql_query($perfsQuery, $db_link);
$max_stories = $padrão;
if ($linha = mysql_fetch_assoc($resultado)) {
$max_stories = $row['max_stories'];
}
retornar $max_stories;
}
função writeRssFeed($usuário)
{
//Obtém as informações de conexão do banco de dados
$configurações = parse_ini_file("rss_server.ini");
// procura as preferências do usuário...
$link = mysql_connect($configurações['db_host'], $configurações['usuário'],
$configurações['senha']) OU morrer(mysql_error());
$max_stories = getUserMaxStories($link, 25);
//vai pegar meus dados
$newsQuery = sprintf("SELECT * FROM histórias WHERE post_date = '%s'",
mysql_real_escape_string(tempo()));
$resultado = mysql_query($newsQuery, $link);
$feed = createRssHeader();
$i = 0;
//construir o feed...
while ($linha = mysql_fetch_assoc($resultado)) {
if ($i < $max_stories) {
$título = $linha['título'];
$link = $row['link'];
$descrição = $linha['descrição'];
$data = $linha['data'];
$guid = $row['guid'];
$feed .= createRssItem($title, $link, $description, $date, $guid);
$eu++;
} outro {
quebrar;
}
}
mysql_close($link);
$feed .= createRssFooter();
// escreve o feed no servidor...
eco($alimentação);
}
?> Também existem limitações para dividir métodos longos em métodos curtos, e a divisão excessiva será contraproducente. Portanto, não abuse deste bom hábito. Dividir o código em grandes pedaços pode tornar a leitura tão difícil quanto não quebrar o código longo.
Adicionando comentários ao seu código
Adicionar bons comentários ao seu código às vezes pode parecer tão difícil quanto escrevê-lo. Não é fácil saber o que anotar porque muitas vezes tendemos a anotar o que o código está fazendo no momento. É uma boa ideia comentar o propósito do seu código. No bloco de cabeçalho menos óbvio da função, o leitor é informado sobre as entradas e saídas do método, bem como o objetivo original do método.
É comum comentar o que o código está fazendo atualmente, mas isso é desnecessário. Se o código for complexo e você precisar comentar o que ele está fazendo no momento, isso sugerirá que você reescreva o código para torná-lo mais fácil de entender. Aprenda a usar bons nomes e métodos mais curtos para tornar seu código mais legível sem fornecer comentários explicando sua finalidade.
Mau hábito: funções com comentários excessivos ou insuficientes
Os comentários na Listagem 5 apenas informam ao leitor o que o código está fazendo: iterar por meio de um loop ou adicionar um número. Mas ignora por que faz seu trabalho atual. Isso deixa as pessoas que mantêm o código sem saber se o código pode ser alterado com segurança (sem introduzir novos defeitos).
Listagem 5. Mau hábito: muitos ou poucos comentários de função
<?php
classe MensagemResultado
{
privado $gravidade;
mensagem privada $;
função pública __construct($sev, $msg)
{
$this->gravidade = $sev;
$esta->mensagem = $msg;
}
função pública getSeverity()
{
retorne $this->gravidade;
}
função pública setSeverity($severity)
{
$this->severidade = $severidade;
}
função pública getMessage()
{
return $esta->mensagem;
}
função pública setMessage($msg)
{
$esta->mensagem = $msg;
}
}
função cntMsgs($mensagens)
{
$n = 0;
/* itera pelas mensagens... */
foreach($mensagens as $m) {
if ($m->getSeverity() == 'Erro') {
$n++; // adiciona um ao resultado;
}
}
retornar$n;
}
$mensagens = array(new ResultMessage("Erro", "Isto é um erro!"),
new ResultMessage("Aviso", "Isto é um aviso!"),
new ResultMessage("Erro", "Este é outro erro!"));
$errs = cntMsgs($messages);
echo("Há erros " . $errs . " no resultado.n");
Boa
prática: Funções e classes anotadas
Os comentários na Listagem 6 informam ao leitor sobre classes e métodos. propósito. Este comentário explica por que o código está fazendo seu trabalho atual, o que pode ser útil na manutenção do código no futuro. O código pode precisar ser modificado à medida que as condições mudam, mas as modificações são fáceis se o propósito do código for facilmente compreendido.
Listagem 6. Boas práticas: funções e classes anotadas
<?php
/**
* A classe ResultMessage contém uma mensagem que pode ser retornada
* como resultado de um processo A mensagem tem uma gravidade e.
* mensagem.
*
* @autor nagood
*
*/
classe ResultadoMessage
{
privado $gravidade;
mensagem privada $;
/**
* Construtor para ResultMessage que permite atribuir
* gravidade e mensagem.
* @param $sev Veja {@link getSeverity()}
* @param $msg
* @return tipo_desconhecido
*/
função pública __construct($sev, $msg)
{
$this->gravidade = $sev;
$esta->mensagem = $msg;
}
/**
* Retorna a gravidade da mensagem. Deve ser um.
* "Informação", "Aviso" ou "Erro".
* @return string Gravidade da mensagem
*/
função pública getSeverity()
{
retorne $this->gravidade;
}
/**
* Define a gravidade da mensagem
* @param $severidade
* @return nulo
*/
função pública setSeverity($severity)
{
$this->severidade = $severidade;
}
função pública getMessage()
{
return $esta->mensagem;
}
função pública setMessage($msg)
{
$esta->mensagem = $msg;
}
}
/*
* Conta as mensagens com a gravidade determinada no array
*de mensagens.
*
* @param $messages Uma matriz de ResultMessage
* @return int Contagem de mensagens com gravidade "Erro"
*/
função countErrors($mensagens)
{
$matchingCount = 0;
foreach($mensagens as $m) {
if ($m->getSeverity() == "Erro") {
$correspondênciaContagem++;
}
}
retornar $contagemcorrespondente;
}
$mensagens = array(new ResultMessage("Erro", "Isto é um erro!"),
new ResultMessage("Aviso", "Isto é um aviso!"),
new ResultMessage("Erro", "Este é outro erro!"));
$errs = countErrors($messages);
echo("Existem " . $errs . " erros no resultado.n")
;
Tratamento de erros
Como regra geral, se você deseja escrever aplicativos robustos, siga a regra 80/20 para tratamento de erros: 80% do seu código é usado para tratar exceções e validação, e 20% do seu código é usado para fazer o trabalho real. Isso geralmente é feito ao codificar a lógica básica (caminho feliz) de um programa. Isso significa escrever um código que funcione nos bastidores, que todos os dados estejam disponíveis e todas as condições sejam as esperadas. Esse código pode ser frágil durante o ciclo de vida do aplicativo. No outro extremo, leva muito tempo para escrever código para condições que você nunca encontrou antes.
Esse hábito exige que você escreva código de tratamento de erros suficiente, em vez de escrever código para lidar com todos os erros, para que o código nunca seja concluído.
Maus hábitos: nenhum tratamento de erros O código
da Listagem 7 demonstra dois maus hábitos. Primeiro, os parâmetros de entrada não são verificados, embora se saiba que parâmetros em determinados estados causarão exceções no método. Segundo, o código chama um método que pode lançar uma exceção, mas não a trata. Quando ocorre um problema, o autor do código ou a pessoa que mantém o código só pode adivinhar a origem do problema.
Listagem 7. Mau hábito: não tratar condições de erro
<?php
// Obtém o nome real do
função convertDayOfWeekToName($dia)
{
$diaNomes = array(
"Domingo",
"Segunda-feira",
"Terça-feira",
"Quarta-feira",
"Quinta-feira",
"Sexta-feira",
"Sábado");
return $diaNomes[$dia];
}
echo("O nome do dia 0 é: " . convertDayOfWeekToName(0) . "n");
echo("O nome do 10º dia é: " . convertDayOfWeekToName(10) . "n");
echo("O nome do dia 'laranja' é: " . convertDayOfWeekToName('orange') . "n")
;
Boas Práticas: Tratamento de Exceções
A Listagem 8 demonstra lançar e tratar exceções de maneira significativa. O tratamento adicional de erros não apenas torna o código mais robusto, mas também melhora a legibilidade do código, tornando-o mais fácil de entender. A forma como as exceções são tratadas é uma boa indicação da intenção do autor original ao escrever o método.
Listagem 8. Boas práticas: tratamento de exceções
<?php
/**
* Esta é a exceção lançada se o dia da semana for inválido.
* @autor nagood
*
*/
class InvalidDayOfWeekException estende a exceção { }
class InvalidDayFormatException estende a exceção { }
/**
* Obtém o nome do dia determinado no dia da semana.
* retorna um erro se o valor fornecido estiver fora do intervalo.
*
* @param $dia
* @return tipo_desconhecido
*/
função convertDayOfWeekToName($dia)
{
if (!is_numeric($dia)) {
throw new InvalidDayFormatException('O valor '' . $day . '' é um ' .
'formato inválido para um dia da semana.');
}
if (($dia > 6) || ($dia < 0)) {
throw new InvalidDayOfWeekException('O número do dia '' . $day . '' é um ' .
'dia da semana inválido. Esperando 0-6.');
}
$diaNomes = array(
"Domingo",
"Segunda-feira",
"Terça-feira",
"Quarta-feira",
"Quinta-feira",
"Sexta-feira",
"Sábado");
return $diaNomes[$dia];
}
echo("O nome do dia 0 é: " . convertDayOfWeekToName(0) . "n")
;
echo("O nome do 10º dia é: " . convertDayOfWeekToName(10) . "n");
} catch (InvalidDayOfWeekException $e) {
echo ("Erro encontrado ao tentar converter o valor: " . $e->getMessage() . "n");
}
tentar {
echo("O nome do dia 'laranja' é: " . convertDayOfWeekToName('orange') . "n");
} catch (InvalidDayFormatException $e) {
echo ("Erro encontrado ao tentar converter o valor: " . $e->getMessage() . "n");
}
?>
Embora a verificação de parâmetros seja uma confirmação - se você precisar que os parâmetros estejam em um determinado estado, isso será útil para as pessoas que usam o método - você deve verificá-los e lançar exceções significativas:
◆ Tratar as exceções o mais fielmente possível Os problemas que surgem estão intimamente relacionados.
◆Tratamento dedicado de cada exceção.
Não use copiar e colar
Você pode copiar e colar código de outro lugar em seu editor de código, mas há prós e contras em fazer isso. O bom é que copiar o código de um exemplo ou template pode evitar muitos erros. A desvantagem é que isso leva facilmente a muitos métodos de programação semelhantes.
Tenha cuidado para não copiar e colar código de uma parte do aplicativo para outra. Se você é assim, pare com esse mau hábito e considere reescrever esse código para ser reutilizável. De modo geral, colocar o código em um só lugar facilita sua manutenção posterior porque ele só precisa ser alterado em um só lugar.
Maus hábitos: trechos de código semelhantes
na Listagem 9 mostram vários métodos quase idênticos, mas com valores diferentes. Existem ferramentas que podem ajudar a encontrar código copiado e colado (consulte Recursos).
Listagem 9. Maus hábitos: trechos de código semelhantes
<?php
/**
* Conta o número de mensagens encontradas no array de
* ResultMessage com o valor getSeverity() de "Error"
*
* @param $messages Uma matriz de ResultMessage
* @return tipo_desconhecido
*/
função countErrors($mensagens)
{
$matchingCount = 0;
foreach($mensagens as $m) {
if ($m->getSeverity() == "Erro") {
$correspondênciaContagem++;
}
}
retornar $contagemcorrespondente;
}
/**
* Conta o número de mensagens encontradas no array de
* ResultMessage com o valor getSeverity() de "Aviso"
*
* @param $messages Uma matriz de ResultMessage
* @return tipo_desconhecido
*/
função contagemAvisos($mensagens)
{
$matchingCount = 0;
foreach($mensagens as $m) {
if ($m->getSeverity() == "Aviso") {
$correspondênciaContagem++;
}
}
retornar $contagemcorrespondente;
}
/**
* Conta o número de mensagens encontradas no array de
* ResultMessage com o valor getSeverity() de "Information"
*
* @param $messages Uma matriz de ResultMessage
* @return tipo_desconhecido
*/
função contagemInformações($mensagens)
{
$matchingCount = 0;
foreach($mensagens as $m) {
if ($m->getSeverity() == "Informações") {
$correspondênciaContagem++;
}
}
retornar $contagemcorrespondente;
}
$mensagens = array(new ResultMessage("Erro", "Isto é um erro!"),
new ResultMessage("Aviso", "Isto é um aviso!"),
new ResultMessage("Erro", "Este é outro erro!"));
$errs = countErrors($messages);
echo("Existem " . $errs . " erros no resultado.n");
?>
Boa Prática: Funções Reutilizáveis com Parâmetros
A Listagem 10 mostra o código modificado, que coloca o código copiado em um método. Outro método também foi alterado e agora delega tarefas ao novo método. Construir uma abordagem comum leva tempo para ser projetado e isso permite que você pare e pense, em vez de copiar e colar instintivamente. Mas o tempo investido numa abordagem comum será recompensado quando forem necessárias alterações.
Listagem 10. Boas práticas: funções reutilizáveis com parâmetros
<?php
/*
* Conta as mensagens com a gravidade determinada no array
*de mensagens.
*
* @param $messages Uma matriz de ResultMessage
* @return int Contagem de mensagens correspondentes a $withSeverity
*/
function countMessages($mensagens, $withSeverity)
{
$matchingCount = 0;
foreach($mensagens as $m) {
if ($m->getSeverity() == $withSeverity) {
$correspondênciaContagem++;
}
}
retornar $contagemcorrespondente;
}
/**
* Conta o número de mensagens encontradas no array de
* ResultMessage com o valor getSeverity() de "Error"
*
* @param $messages Uma matriz de ResultMessage
* @return tipo_desconhecido
*/
função countErrors($mensagens)
{
return contagemMensagens($mensagens, "Erros");
}
/**
* Conta o número de mensagens encontradas no array de
* ResultMessage com o valor getSeverity() de "Aviso"
*
* @param $messages Uma matriz de ResultMessage
* @return tipo_desconhecido
*/
função contagemAvisos($mensagens)
{
return contagemMensagens($mensagens, "Aviso");
}
/**
* Conta o número de mensagens encontradas no array de
* ResultMessage com o valor getSeverity() de "Aviso"
*
* @param $messages Uma matriz de ResultMessage
* @return tipo_desconhecido
*/
função contagemInformação($mensagens)
{
return contagemMensagens($mensagens, "Informações");
}
$mensagens = array(new ResultMessage("Erro", "Isto é um erro!"),
new ResultMessage("Aviso", "Isto é um aviso!"),
new ResultMessage("Erro", "Este é outro erro!"));
$errs = countErrors($messages);
echo("Há erros " . $errs . " no resultado.n");
Conclusão
Se
você desenvolver os bons hábitos discutidos neste artigo ao escrever código PHP, você irá. ser capaz de construir código que seja fácil de ler, entender e manter. O código sustentável construído dessa forma reduzirá o risco de depuração, correção e extensão do código.
Usar bons nomes e métodos mais curtos melhora a legibilidade do código. O objetivo de comentar o código é facilitar a compreensão e expansão do código. O tratamento adequado dos erros torna seu código mais robusto. Por fim, pare de copiar e colar para manter seu código limpo e melhorar a reutilização.