Princípios de Código Limpo para XOOPS
Visão Geral
Seção intitulada “Visão Geral”Código limpo é código que é fácil de ler, entender e manter. Este guia cobre princípios de código limpo especificamente aplicados ao desenvolvimento de módulos XOOPS.
Princípios Principais
Seção intitulada “Princípios Principais”mindmap root((Código Limpo)) Legibilidade Nomes Significativos Funções Pequenas Comentários Quando Necessário Simplicidade Responsabilidade Única Princípio DRY Princípio KISS Manutenibilidade Estilo Consistente Tratamento de Erros TestesNomes Significativos
Seção intitulada “Nomes Significativos”Variáveis
Seção intitulada “Variáveis”// Ruim$d = new DateTime();$u = $memberHandler->getUser($id);$arr = [];
// Bom$createdDate = new DateTime();$currentUser = $memberHandler->getUser($userId);$publishedArticles = [];Funções
Seção intitulada “Funções”// Ruimfunction process($data) { ... }function handle($item) { ... }function doStuff($x, $y) { ... }
// Bomfunction publishArticle(Article $article): void { ... }function calculateTotalPrice(array $items): float { ... }function sendNotificationEmail(User $user, string $subject): bool { ... }Classes
Seção intitulada “Classes”// Ruimclass Manager { ... }class Helper { ... }class Utils { ... }
// Bomclass ArticleRepository { ... }class NotificationService { ... }class PermissionChecker { ... }Funções Pequenas
Seção intitulada “Funções Pequenas”Responsabilidade Única
Seção intitulada “Responsabilidade Única”// Ruim - faz muitas coisasfunction processArticle($data) { // Validar if (empty($data['title'])) { throw new Exception('Título necessário'); } // Salvar $article = new Article(); $article->setTitle($data['title']); $this->repository->save($article); // Notificar $this->mailer->send($article->getAuthor(), 'Artigo publicado'); // Log $this->logger->info('Artigo criado'); return $article;}
// Bom - cada função faz uma coisafunction validateArticleData(array $data): void{ if (empty($data['title'])) { throw new ValidationException('Título necessário'); }}
function createArticle(array $data): Article{ $this->validateArticleData($data); return Article::create($data['title'], $data['content']);}
function publishArticle(Article $article): void{ $this->repository->save($article); $this->notifyAuthor($article); $this->logArticleCreation($article);}Comprimento de Função
Seção intitulada “Comprimento de Função”Manter funções curtas - idealmente menos de 20 linhas:
// Bom - função focadapublic function getPublishedArticles(int $limit = 10): array{ $criteria = new CriteriaCompo(); $criteria->add(new Criteria('status', 'published')); $criteria->setSort('published_at'); $criteria->setOrder('DESC'); $criteria->setLimit($limit);
return $this->repository->getObjects($criteria);}Princípio DRY (Não Repita Você Mesmo)
Seção intitulada “Princípio DRY (Não Repita Você Mesmo)”Extrair Código Comum
Seção intitulada “Extrair Código Comum”// Ruim - código repetidofunction getActiveUsers() { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('level', 0, '>')); $criteria->setSort('uname'); return $this->userHandler->getObjects($criteria);}
function getActiveAdmins() { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('level', 0, '>')); $criteria->add(new Criteria('is_admin', 1)); $criteria->setSort('uname'); return $this->userHandler->getObjects($criteria);}
// Bom - lógica compartilhada extraídafunction getUsers(CriteriaCompo $criteria): array{ $criteria->add(new Criteria('level', 0, '>')); $criteria->setSort('uname'); return $this->userHandler->getObjects($criteria);}
function getActiveUsers(): array{ return $this->getUsers(new CriteriaCompo());}
function getActiveAdmins(): array{ $criteria = new CriteriaCompo(); $criteria->add(new Criteria('is_admin', 1)); return $this->getUsers($criteria);}Tratamento de Erros
Seção intitulada “Tratamento de Erros”Usar Exceções Apropriadamente
Seção intitulada “Usar Exceções Apropriadamente”// Ruim - exceções genéricasthrow new Exception('Erro');
// Bom - exceções específicasthrow new ArticleNotFoundException($articleId);throw new PermissionDeniedException('Não pode editar artigo');throw new ValidationException(['title' => 'Título é obrigatório']);Tratar Erros Graciosamente
Seção intitulada “Tratar Erros Graciosamente”public function findArticle(string $id): ?Article{ try { return $this->repository->findById($id); } catch (DatabaseException $e) { $this->logger->error('Erro de banco de dados ao encontrar artigo', [ 'id' => $id, 'error' => $e->getMessage() ]); throw new ServiceException('Não foi possível recuperar artigo', 0, $e); }}Comentários
Seção intitulada “Comentários”Quando Comentar
Seção intitulada “Quando Comentar”// Ruim - comentário óbvio// Incrementar contador$counter++;
// Bom - explica por quê, não o quê// Cache por 1 hora para reduzir carga no banco de dados durante tráfego pico$cache->set($key, $data, 3600);
// Bom - documenta algoritmo complexo/** * Calcular pontuação de relevância do artigo usando algoritmo TF-IDF. * Pontuações maiores indicam melhor correspondência com termos de pesquisa. */function calculateRelevanceScore(Article $article, array $terms): float{ // ...}Organização de Código
Seção intitulada “Organização de Código”Estrutura de Classe
Seção intitulada “Estrutura de Classe”class ArticleService{ // 1. Constantes private const MAX_TITLE_LENGTH = 255;
// 2. Propriedades private ArticleRepository $repository; private EventDispatcher $events;
// 3. Construtor public function __construct( ArticleRepository $repository, EventDispatcher $events ) { $this->repository = $repository; $this->events = $events; }
// 4. Métodos públicos public function publish(Article $article): void { ... } public function archive(Article $article): void { ... }
// 5. Métodos privados private function validateForPublication(Article $article): void { ... }}Lista de Verificação de Código Limpo
Seção intitulada “Lista de Verificação de Código Limpo”- Nomes são significativos e pronunciáveis
- Funções fazem apenas uma coisa
- Funções são pequenas (< 20 linhas)
- Sem código duplicado
- Tratamento de erros apropriado com exceções específicas
- Comentários explicam “por quê”, não “o quê”
- Formatação e estilo consistentes
- Sem números mágicos ou strings
- Dependências são injetadas, não criadas
Documentação Relacionada
Seção intitulada “Documentação Relacionada”- Organização-de-Código
- Tratamento-de-Erros
- Boas-Práticas-de-Testes
- Padrões-PHP