A trick to improve your class names: use suffixes

Ce părere aveți despre treaba asta?

- CalculateStatistics
+ CalculateStatisticsCommand

Mie mi se pare overkill și cred că dacă este ceva ce îmi displace la Laravel este acest suffix la toate clasele.

Adică am două clase:

  • src\commands\CalculateStatistics.php și
  • src\jobs\CalculateStatistics.php

Fiecare din ele stă în propriul namespace: App\commands respectiv App\jobs.

Nu este suficient să ai descrierea asta în path ȘI în namespace? Trebuie să o ai și în numele clasei? De ce să ne oprim aici? Putem duce mai departe povestea, putem sufix și la metode! De ce să avem show și nu showPhotosController? Sau getPhotoModel?

În ghidul Spatie zice așa:

Generally controllers are named by the plural form of their corresponding resource and a Controller suffix. This is to avoid naming collisions with models that are often equally named.

1 Like

Mie îmi place asta la Laravel și o făceam și eu oricum dinainte.

Face codul mult mai lizibil decât să dau scroll să văd din ce namespace import clasa.

Dar e o chestie subiectivă până la urmă.

2 Likes

I general e ok sai suffix sau prefix, eg I interface E enum etc, iti intrerupe flow-ul sa vezi in ce namespace sau path este, mai ales daca ai multe tipuri, insa ca orice in programare it depends, poate sa fie si overkill , denumirele foare luni la fel nu sunt bune.

E-ul din enum vine de la enum.
In C# ai IMyInterface.

Atata timp cat nu minti despre ce este de fapt clasa aia, nici in namespace, nici in denumire, e fix alegerea ta, desi uneori nu vad de ce te-ai repeta atat in namespace cat si in clasa.

use Some\Name\Space\Commands\Bla as BlaCommand;
use Some\Name\Space\Repositories\Bla as BlaRepository
use Some\Other\Name\Space\NotCommand\Bla;

vs

use Some\Name\Space\Commands\BlaCommand;
use Some\Name\Space\Repositories\BlaRepository;
use Some\Oher\Name\Space\NotCommand\Bla;
1 Like

This is to avoid naming collisions with models that are often equally named.

Exemplul asta e cel mai bun motiv ca sa adaugi sufixe, daaaar in php mai poti sa importi si namespace-uri partiale.

@alescx era pe drumul cel bun cu aliases, dar trebuie sa scrii cod mai mult pentru asta si sa duplici numele practic

use Some\Name\Space\Command\Bla as BlaCommand;
use Some\Name\Space\Repository\Bla as BlaRepository;

Eu intotdeauna merg pe varianta fara sufix, sunt de parere ca namespace-ul este foarte declarativ incat sa nu mai pun Controller in numele clasei cand deja exista in namespace.

use Some\Name\Space\Command;
use Some\Name\Space\Repository;

new Command\Bla();
new Repository\Bla();

In felul asta ai distinctia intre Command si Repository cu cat mai putin text scris.

1 Like

merge si cum spui tu si prefer notatia asta cand numele claselor sunt neprefixate. dar daca dai peste un proiect care e organizat cu picioarele (\Some\Name\Space\Repository\Some\More\Name\Space\Etc…) atunci ce spui tu devine foarte verbal.

si da, am intalnit situatia descrisa mai sus. pt ca aparent e foarte greu pt majoritatea sa mentii o structura logica si usor de inteles.

PS: In general, daca lucrez cu un framework, voi incerca sa respect standardele impuse de framework.

Sa adaug un pic din experienta cu Symfony. Fara sufix as avea intr-un bundle (pachet) o clasa-entitate in directorul Entities, una in directorul Controllers, una in directorul Services, ceea ce ar fi ok ca nu sunt conflicte datorita namespaceurilor. Problema e cand vreau sa folosesc toate cele 3 clase intr-un alt fisier: fara sufix ar trebui sa am o regula sa folosesc aliasuri si sa fiu consistent cu regula asta in tot proiectul. Cu sufixe insa o sa am Entitate (singura FARA sufix), EntitateController si EntitateService, si am rezolvat problema. Mai pot avea EntitateType (formular), EntitateRepository (BD), EntitateCommand, etc. “Trickul” asta are vreo 15 ani vechime :slight_smile:

2 Likes

Eu unul folosesc sufixe pentru anumite tipuri de clase

  • joburi
  • comenzi
  • interfete
  • traituri (ma rog, nu sunt clase)
  • dto
1 Like

Cand lucram cu PHP si in proiecte symfony mereu aveam sufixe la clase. Daaar…succesul proiectului tau nu va fi determinat de folosirea prefixelor si sufixelor :slight_smile:

Totusi…am lucrat la un moment dat in 2019 pe un proiect nou la care s-a decis renuntarea la sufixe. Motivele sunt cam tot alea mentionate de mai sus. Ce pot sa spun e ca cel mai enervant lucru era cand doreai sa cauti o clasa, sa ii zicem orientativ Product in PHPStorm. Si apasai de 2x shift si pam…6-7 rezultate Product in dropdown. Ok,ok…aparea namespace-ul acolo…scris minuscul in partea stanga(cateodata chiar imi aduc aminte cele mai mici detalii :grinning: ), dar cat timp pierdeam zilnic facand scroll…pfff. Doar pentru ca cineva a decis ca Product sa fie aceeasi denumire si pentru Controller, Entity, Service, Repository, Interface si Dtos.

Acum nu mai stiu cum e. S-au schimbat multe in lumea PHP inclusiv in PHPStorm. Dar cu siguranta nu mai doresc sa lucrez asa.

2 Likes

pentru controllere, servicii, repositoryuri, nu vad alta varianta decat folosirea sufixelor:

controllers:

    - UsersController
    - ProductsController

services:

    - UsersService (cu interfata IUsersService)
    - ProductsServices (cu interfata IUsersService)

repositories:

    - UsersRepository (cu interfata IUsersRepository)
    - ProductsRepository (cu interfata IProductsRepository)

repourile le impachetez intr-un folder /data, unde mai am si entities.{User, Product} (parca domain este denumirea populara, insa eu m-am obisnuit cu data). Daca nu am un ORM, folosesc si clase statice (UserQueries, ProductQueries) pentru generare queryuri pentru a tine repourile cat mai curate, deci apare si folderul /data/queries. Mi se pare putin cam exagerat sa folosesc sufix si pentru entitati, mai ales ca incerc sa le folosesc doar in repouri.

Pentru controllere si servicii folosesc dtouri (sau modele le zic eu), clase simple ce contin doar fielduri. Validari si alte metode auxiliare, toate sunt in servicii. Asa m-am obisnuit in .Net Core, asa am lucrat si in angular (frontend), asa am continuat si in Scala. Cred ca, conteaza si cat de mult iti permite limbajul sa te joci. In C#, acolo unde foloseam User si din dtouri si din entitati (in servicii de cele mai multe ori), respectam o regula: importam calea dtourilor si foloseam clasa User, iar pentru entitati importam calea pana la penultimul namespace, si foloseam Entities.User unde aveam nevoie.

1 Like

In Java pun clasele in pachete. Daca am un pachet com.mycompany.xyz pun clasa fara sufix. Stiu ca o gasesc acolo.

In cazul claselor service, repositoy, controller folosesc acele sufixe. Cam ce a zis si @AlleXyS

2 Likes