Ren kode principper for XOOPS
Oversigt
Sektion kaldt “Oversigt”Ren kode er kode, der er let at læse, forstå og vedligeholde. Denne vejledning dækker principper for ren kode, der specifikt anvendes til udvikling af XOOPS-moduler.
Kerneprincipper
Sektion kaldt “Kerneprincipper”mindmap root((Clean Code)) Readability Meaningful Names Small Functions Comments When Needed Simplicity Single Responsibility DRY Principle KISS Principle Maintainability Consistent Style Error Handling TestingMeningsfulde navne
Sektion kaldt “Meningsfulde navne”Variabler
Sektion kaldt “Variabler”// Bad$d = new DateTime();$u = $memberHandler->getUser($id);$arr = [];
// Good$createdDate = new DateTime();$currentUser = $memberHandler->getUser($userId);$publishedArticles = [];Funktioner
Sektion kaldt “Funktioner”// Badfunction process($data) { ... }function handle($item) { ... }function doStuff($x, $y) { ... }
// Goodfunction publishArticle(Article $article): void { ... }function calculateTotalPrice(array $items): float { ... }function sendNotificationEmail(User $user, string $subject): bool { ... }Klasser
Sektion kaldt “Klasser”// Badclass Manager { ... }class Helper { ... }class Utils { ... }
// Goodclass ArticleRepository { ... }class NotificationService { ... }class PermissionChecker { ... }Små funktioner
Sektion kaldt “Små funktioner”Enkelt ansvar
Sektion kaldt “Enkelt ansvar”// Bad - does too many thingsfunction processArticle($data) { // Validate if (empty($data['title'])) { throw new Exception('Title required'); } // Save $article = new Article(); $article->setTitle($data['title']); $this->repository->save($article); // Notify $this->mailer->send($article->getAuthor(), 'Article published'); // Log $this->logger->info('Article created'); return $article;}
// Good - each function does one thingfunction validateArticleData(array $data): void{ if (empty($data['title'])) { throw new ValidationException('Title required'); }}
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);}Funktionslængde
Sektion kaldt “Funktionslængde”Hold funktioner korte - ideelt set under 20 linjer:
// Good - focused functionpublic 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);}DRY Princip (Gentag ikke dig selv)
Sektion kaldt “DRY Princip (Gentag ikke dig selv)”Uddrag fælles kode
Sektion kaldt “Uddrag fælles kode”// Bad - repeated codefunction 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);}
// Good - shared logic extractedfunction 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);}Fejlhåndtering
Sektion kaldt “Fejlhåndtering”Brug undtagelser korrekt
Sektion kaldt “Brug undtagelser korrekt”// Bad - generic exceptionsthrow new Exception('Error');
// Good - specific exceptionsthrow new ArticleNotFoundException($articleId);throw new PermissionDeniedException('Cannot edit article');throw new ValidationException(['title' => 'Title is required']);Håndter fejl elegant
Sektion kaldt “Håndter fejl elegant”public function findArticle(string $id): ?Article{ try { return $this->repository->findById($id); } catch (DatabaseException $e) { $this->logger->error('Database error finding article', [ 'id' => $id, 'error' => $e->getMessage() ]); throw new ServiceException('Unable to retrieve article', 0, $e); }}Kommentarer
Sektion kaldt “Kommentarer”Hvornår skal man kommentere
Sektion kaldt “Hvornår skal man kommentere”// Bad - obvious comment// Increment counter$counter++;
// Good - explains why, not what// Cache for 1 hour to reduce database load during peak traffic$cache->set($key, $data, 3600);
// Good - documents complex algorithm/** * Calculate article relevance score using TF-IDF algorithm. * Higher scores indicate better match with search terms. */function calculateRelevanceScore(Article $article, array $terms): float{ // ...}Kode Organisation
Sektion kaldt “Kode Organisation”Klassestruktur
Sektion kaldt “Klassestruktur”class ArticleService{ // 1. Constants private const MAX_TITLE_LENGTH = 255;
// 2. Properties private ArticleRepository $repository; private EventDispatcher $events;
// 3. Constructor public function __construct( ArticleRepository $repository, EventDispatcher $events ) { $this->repository = $repository; $this->events = $events; }
// 4. Public methods public function publish(Article $article): void { ... } public function archive(Article $article): void { ... }
// 5. Private methods private function validateForPublication(Article $article): void { ... }}Tjekliste for ren kode
Sektion kaldt “Tjekliste for ren kode”- Navne er meningsfulde og kan udtales
- Funktioner gør kun én ting
- Funktioner er små (< 20 linjer)
- Ingen duplikeret kode
- Korrekt fejlhåndtering med specifikke undtagelser
- Kommentarer forklarer “hvorfor”, ikke “hvad”
- Konsekvent formatering og stil
- Ingen magiske tal eller strenge
- Afhængigheder injiceres, ikke oprettes
Relateret dokumentation
Sektion kaldt “Relateret dokumentation”- Kode organisation
- Fejlhåndtering
- Test af bedste praksis
- PHP standarder