Načela čiste kode za XOOPS
Pregled
Section titled “Pregled”Čista koda je koda, ki jo je enostavno brati, razumeti in vzdrževati. Ta priročnik pokriva načela čiste kode, posebej uporabljena za XOOPS razvoj modulov.
Temeljna načela
Section titled “Temeljna načela”mindmap root((Clean Code)) Readability Meaningful Names Small Functions Comments When Needed Simplicity Single Responsibility DRY Principle KISS Principle Maintainability Consistent Style Error Handling TestingPomenljiva imena
Section titled “Pomenljiva imena”Spremenljivke
Section titled “Spremenljivke”// Bad$d = new DateTime();$u = $memberHandler->getUser($id);$arr = [];
// Good$createdDate = new DateTime();$currentUser = $memberHandler->getUser($userId);$publishedArticles = [];Funkcije
Section titled “Funkcije”// 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 { ... }Razredi
Section titled “Razredi”// Badclass Manager { ... }class Helper { ... }class Utils { ... }
// Goodclass ArticleRepository { ... }class NotificationService { ... }class PermissionChecker { ... }Majhne funkcije
Section titled “Majhne funkcije”Ena odgovornost
Section titled “Ena odgovornost”// 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);}Dolžina funkcije
Section titled “Dolžina funkcije”Funkcije naj bodo kratke - idealno manj kot 20 vrstic:
// 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 Načelo (ne ponavljaj se)
Section titled “DRY Načelo (ne ponavljaj se)”Izvleček skupne kode
Section titled “Izvleček skupne 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);}Obravnava napak
Section titled “Obravnava napak”Uporabite izjeme pravilno
Section titled “Uporabite izjeme pravilno”// 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']);Uglajeno obravnavajte napake
Section titled “Uglajeno obravnavajte napake”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); }}Komentarji
Section titled “Komentarji”Kdaj komentirati
Section titled “Kdaj komentirati”// 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{ // ...}Organizacija kode
Section titled “Organizacija kode”Struktura razreda
Section titled “Struktura razreda”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 { ... }}Kontrolni seznam čiste kode
Section titled “Kontrolni seznam čiste kode”- Imena so smiselna in izgovorljiva
- Funkcije naredijo samo eno stvar
- Funkcije so majhne (< 20 vrstic)
- Brez podvojene kode
- Pravilno obravnavanje napak s posebnimi izjemami
- Komentarji pojasnjujejo “zakaj”, ne “kaj”
- Dosledno oblikovanje in slog
- Brez čarobnih števil ali nizov
- Odvisnosti so vstavljene, ne ustvarjene
Povezana dokumentacija
Section titled “Povezana dokumentacija”- Organizacija kode
- Obravnava napak
- Testiranje najboljših praks
- PHP Standardi