Jmenné prostory – Last Call Announcement
- David Grudl
- Nette Core | 8218
Dnes proběhne velký třesk a dojde k úpravě jmenných prostorů ve frameworku. Změna se týká skutečně velkého počtu tříd. Je jasné, že přejmenovávání nepatří mezi populární úpravy, nicméně přechod by měl být bezbolestný.
Důvody
Nette Framework je dost možná prvním PHP frameworkem na světě, který používání jmenných prostorů zavedl. Kvůli prodlevám s vydáním PHP 5.3 se začaly v praxi používat docela pozdě a tudíž mají stále svou první a dnes již historickou podobu. Ta neodpovídá současnému stavu frameworku a před vydáním klíčové verze 2.0 je záhodno ji upravit.
Zpětná kompatibilita
Úpravy se týkají pouze verze pro PHP 5.3, ve verzích pro 5.2 k žádným změnám nedojde. Rozevírají se tím sice nůžky mezi 5.3 a 5.2 verzemi, nicméně podpora 5.2 stejně časem skončí.
Ve verzi pro 5.3 bude zajištěna 100% zpětná kompatibilita. Při
použití starého názvu třídy se bude jen emitovat hláška úrovně
E_USER_DEPRECATED. Bude k dispozici nástroj Class-Updater, který
detekuje použití starého názvu třídy ve vašem kódu a
opraví je.
Pravidla pojmenování
Novou podobu názvů tříd jsem chtěl podřídit, jako v podstatě vše v Nette, pohodlí programátora. Jak ukázala řada diskusí, subjektivní požadavky mohou být rozporuplné. Pro někoho znamená pohodlí mít co nejkratší názvy tříd, pro jiného jsou to názvy co nejvíce popisné.
Najít nějaká formální pravidla není vůbec snadné, často je lepší rozhodovat citem, každopádně první pravidlo a další doporučení (v sestupné důležitosti) se dodržují:
a) třída musí mít výstižný název i bez uvedení jmenného prostoru
Název každé třídy i bez jmenného prostoru musí vystihovat její podstatu, tj. název musí obsahovat podmět. Příklady:
- chybně:
Nette\Application\Routers\Simple
– nelze dovodit, že Simple je router - chybně:
Nette\Application\Responses\Download
– nelze dovodit, že Download je odpověď - chybně:
Nette\Database\Drivers\MsSql
– MsSql je název databáze - dobře:
Nette\Database\Drivers\MsSqlDriver
– už je jasné, že jde o driver pro MsSql - dobře:
Nette\Forms\Controls\Button
– pokud existuje jednoslovný výraz, je to ideální
(Výstižný pochopitelně musí být samotný název jmenného prostoru, výhodou je název kratší.)
b) bez zbytečných duplicit
Název třídy a název prostoru by neměly pokud možno duplicitně obsahovat stejnou informaci.
- místo
Nette\Latte\LatteFilter
radějiNette\Latte\Filter
- místo
Nette\Http\HttpRequest
radějiNette\Http\Request
Pak se i zjednodušuje používání use, stačí importovat celé
use Nette\Http;
a poté přistupovat k třídám přes
Http\Request
, Http\Response
apod.
c) nezaměnitelnost tříd z více prostorů
Pokud se v kódu často používají vedle sebe dvě třídy z různých prostorů, nebo pokud mají mezi sebou jinou souvislost, neměly by mít stejný název. Jinými slovy, nemělo by být nutné používat AS v klauzuli USE.
d) závislosti
- Třídy ze jmenného prostoru A\B by neměly mít závislost na třídy z prostoru A\B\C.
- Pokud má třída ze jmenného prostoru A\B závislost na třídě ze jmenného prostoru A\C, neměla by žádná třída z A\C mít závislost na A\B
(Toho nebude však zcela docíleno pouhým přejmenováním)
e) nezařazené třídy
Primárním úkolem jmenných prostorů je zavést do frameworku pořádek a přehlednost, sjednotit logické celky, nikoliv třídy samoúčelně kategorizovat. Problém tak vzniká u tříd, které přirozeně nezapadají do žádného existujícího celku. Příkladem může být třída Finder, kterou lze smysluplně zařadit hned do několika jmenných prostorů:
Nette\Finder
– „zapleveluje“ jmenný prostor NetteNette\Tools\Finder
– přesun to Nette\Tools je spíš jen zametením předchozí situace pod koberecNette\Finder\Finder
– samostatný jmenný prostor vede k nepěknému zdvojování názvůNette\FileSystem\Finder
– srozumitelný název, výstižnější než samotné Nette\FinderNette\FileSystem\Tools\Finder
– oproti předchozímu nic nepřináší, jen je delší
Totéž se týká celé řady dalších tříd, od Nette\Json
přes Nette\Image
po Nette\Object
. Pro tyto třídy
navíc platí, že se jejich název v kódu často používá. Z hlediska
pohodlí programátora se pak jeví jako nejvýhodnější zůstat
u jednoduchého prostoru Nette a uměle ho neprodlužovat.
f) sdružující jmenné prostory
Dalším případem jsou jmenné prostory sdružující např. různé implementace téhož rozhraní apod. Příklad:
- Nette\Caching\Storages\FileStorage, MemcachedStorage, … – všechny úložiště v samostatném prostoru Nette\Caching\Storages
Sdružující namespace prodlužuje název, protože Storage
nelze z názvu třídy zpravidla odstranit (pravidlo a) a tím pádem porušuje
doporučení b). Význam namespace je tak čistě kategorizační. Výhodou je
lepší orientace v API dokumentaci (téhož by však šlo dosáhnout jinak,
např. anotací @package), možná i snazší dostupnost při použití
plnohodnotných IDE. Sdružující jmenné prostory by se tedy měly používat
co nejméně a rozvážně.
g) ohled na budoucí vývoj
Některé změny namespaces předjímají budoucí vývoj frameworku
(Nette\Application\UI
). Obdobně nedošlo ke změnám tam, kde se
chystá jiná úprava (Nette\Forms
).
h) třídy výjimek
Do jmenného prostoru Nette byly zahrnuty i výjimky.
Last Call Announcement
Pokud je zde někdo, kdo má jakékoliv konstruktivní připomínky, nechť promluví teď nebo ať mlčí navždy.
- David Grudl
- Nette Core | 8218
Nové jmenné prostory
Přehled všech tříd se změněným názvem:
- bez prostoru
InvalidStateException
→Nette\InvalidStateException
NotImplementedException
→Nette\NotImplementedException
NotSupportedException
→Nette\NotSupportedException
DeprecatedException
→Nette\DeprecatedException
MemberAccessException
→Nette\MemberAccessException
FatalErrorException
→Nette\FatalErrorException
- ArgumentOutOfRangeException (zrušeno)
- Nette
IComponent
→Nette\ComponentModel\IComponent
Component
→Nette\ComponentModel\Component
IComponentContainer
→Nette\ComponentModel\IContainer
ComponentContainer
→Nette\ComponentModel\Container
AmbiguousServiceException
→Nette\DI\AmbiguousServiceException
IContext
→Nette\DI\IContext
Context
→Nette\DI\Context
Configurator
→Nette\DI\Configurator
Debug
→Nette\Diagnostics\Debugger
DebugPanel
→Nette\Diagnostics\Panel
IDebugPanel
→Nette\Diagnostics\IPanel
DebugHelpers
→Nette\Diagnostics\Helpers
ITranslator
→Nette\Localization\ITranslator
SafeStream
→Nette\Utils\SafeStream
Finder
→Nette\Utils\Finder
ArrayTools
→Nette\Utils\Arrays
Json
→Nette\Utils\Json
Neon
→Nette\Utils\Neon
Paginator
→Nette\Utils\Paginator
String
→Nette\Utils\Strings
Tools
→ rozděleno do třídNette\DateTime
Nette\Utils\CriticalSection
Nette\Utils\MimeTypeDetector
CallbackFilterIterator
→Nette\Iterators\Filter
GenericRecursiveIterator
→Nette\Iterators\Recursor
InstanceFilterIterator
→Nette\Iterators\InstanceFilter
MapIterator
→Nette\Iterators\Mapper
RecursiveCallbackFilterIterator
→Nette\Iterators\RecursiveFilter
SmartCachingIterator
→Nette\Iterators\CachingIterator
- Nette\Application
PresenterRequest
→Nette\Application\Request
IPresenterResponse
→Nette\Application\IResponse
DownloadResponse
→Nette\Application\Responses\FileResponse
ForwardingResponse
→Nette\Application\Responses\ForwardResponse
JsonResponse
→Nette\Application\Responses\JsonResponse
RedirectingResponse
→Nette\Application\Responses\RedirectResponse
RenderResponse
→Nette\Application\Responses\TextResponse
CliRouter
→Nette\Application\Routers\CliRouter
MultiRouter
→Nette\Application\Routers\RouteList
Route
→Nette\Application\Routers\Route
SimpleRouter
→Nette\Application\Routers\SimpleRouter
RoutingDebugger
→Nette\Application\Diagnostics\RoutingPanel
Link
→Nette\Application\UI\Link
IRenderable
→Nette\Application\UI\IRenderable
ISignalReceiver
→Nette\Application\UI\ISignalReceiver
IStatePersistent
→Nette\Application\UI\IStatePersistent
IPartiallyRenderable
→Nette\Application\UI\IPartiallyRenderable
Presenter
→Nette\Application\UI\Presenter
PresenterComponent
→Nette\Application\UI\PresenterComponent
PresenterComponentReflection
→Nette\Application\UI\PresenterComponentReflection
Control
→Nette\Application\UI\Control
AppForm
→Nette\Application\UI\Form
BadSignalException
→Nette\Application\UI\BadSignalException
InvalidLinkException
→Nette\Application\UI\InvalidLinkException
- Nette\Forms
Button
→Nette\Forms\Controls\Button
Checkbox
→Nette\Forms\Controls\Checkbox
FileUpload
→Nette\Forms\Controls\UploadControl
FormControl
→Nette\Forms\Controls\BaseControl
HiddenField
→Nette\Forms\Controls\HiddenField
ImageButton
→Nette\Forms\Controls\ImageButton
MultiSelectBox
→Nette\Forms\Controls\MultiSelectBox
RadioList
→Nette\Forms\Controls\RadioList
SelectBox
→Nette\Forms\Controls\SelectBox
SubmitButton
→Nette\Forms\Controls\SubmitButton
TextArea
→Nette\Forms\Controls\TextArea
TextBase
→Nette\Forms\Controls\TextBase
TextInput
→Nette\Forms\Controls\TextInput
FormGroup
→Nette\Forms\ControlGroup
FormContainer
→Nette\Forms\Container
IFormControl
→Nette\Forms\IControl
DefaultFormRenderer
→Nette\Forms\Rendering\DefaultFormRenderer
- Nette\Caching
ICacheStorage
→Nette\Caching\IStorage
DummyStorage
→Nette\Caching\Storages\DevNullStorage
FileJournal
→Nette\Caching\Storages\FileJournal
FileStorage
→Nette\Caching\Storages\FileStorage
ICacheJournal
→Nette\Caching\Storages\IJournal
MemcachedStorage
→Nette\Caching\Storages\MemcachedStorage
MemoryStorage
→Nette\Caching\Storages\MemoryStorage
- Nette\Config
ConfigAdapterIni
→Nette\Config\IniAdapter
ConfigAdapterNeon
→Nette\Config\NeonAdapter
IConfigAdapter
→Nette\Config\IAdapter
- Nette\Database\Selector
GroupedTableSelection
→Nette\Database\Table\GroupedSelection
TableRow
→Nette\Database\Table\ActiveRow
TableSelection
→Nette\Database\Table\Selection
- Nette\Loaders
LimitedScope
→Nette\Utils\LimitedScope
- Nette\Mail
Mail
→Nette\Mail\Message
MailMimePart
→Nette\Mail\MimePart
- Nette\Reflection
ClassReflection
→Nette\Reflection\ClassType
ExtensionReflection
→Nette\Reflection\Extension
FunctionReflection
→Nette\Reflection\GlobalFunction
MethodReflection
→Nette\Reflection\Method
ParameterReflection
→Nette\Reflection\Parameter
PropertyReflection
→Nette\Reflection\Property
- Nette\Templates
LatteFilter
→Nette\Latte\Engine
LatteMacros
→Nette\Latte\DefaultMacros
LatteException
→Nette\Latte\ParseException
CachingHelper
→Nette\Caching\OutputHelper
TemplateException
→Nette\Templating\FilterException
TemplateCachestorage
→Nette\Templating\PhpFileStorage
TemplateHelpers
→Nette\Templating\DefaultHelpers
TemplateFilters
→ přesunuto do doplňků
- Nette\Web
Html
→Nette\Utils\Html
HttpContext
→Nette\Http\Context
IHttpRequest
→Nette\Http\IRequest
HttpRequest
→Nette\Http\Request
IHttpResponse
→Nette\Http\IResponse
HttpResponse
→Nette\Http\Response
HttpRequestFactory
→Nette\Http\RequestFactory
HttpUploadedFile
→Nette\Http\FileUpload
ISessionStorage
→Nette\Http\ISessionStorage
Session
→Nette\Http\Session
SessionNamespace
→Nette\Http\SessionNamespace
Uri
→Nette\Http\Url
UriScript
→Nette\Http\UrlScript
IUser
→Nette\Http\IUser
User
→Nette\Http\User
- Jan Tvrdík
- Nette guru | 2595
Špatně vidím, nebo skutečně chybí IPresenter a BadRequestException? Navrhuji přejmenovat AppForm na Form (v souladu s 2. pravidlem). Dále mi pořád nesedí RoutingDebugger v Application, ale v praxi mi to nevadí, protože ho nikdy neinstancuji.
Teď koukám, že chybí také celé Nette\Forms. Mám to chápat tak, že tam dojde ke změnám zároveň s uvedením nových formulářů?
- paranoiq
- Člen | 392
Lopo
imo je příliš konkrétní a málo používaný. argument může být nevalidní z desítek důvodů. rozpitvávat jen jeden z nich není konzistentní
Jan Tvrdík
AppForm → Form není v souladu s pravidlem c)
David Grudl
pořád se mi nelíbí ta přílišná katalogizace, kvůli které pak porušuješ pravidlo b) (Responses\..Response, Routers\..Router, Helpers\..Helper). jmenné prostory nemusí kopírovat adresářovou strukturu. celé pravidlo f) považuji za špatné
zjednodušil (ponechal tak jak jsou teď) bych také všechny případy, kdy je jméno třídy až na čtvrté úrovni (Application\UI, Application\Diagnostics), ale netuším, jaký bude ‚budoucí vývoj‘ ohledně UI
název třídy Filter považuji za příliš obecný. narozdíl třeba od Request či Response, což jsou celkem zažité pojmy, neříká absoulutně nic o účelu třídy
Editoval paranoiq (5. 4. 2011 9:44)
- Honza Marek
- Člen | 1664
paranoiq napsal(a):
Jan Tvrdík
AppForm → Form není v souladu s pravidlem c)
Je… AppForm s třídou Form jsem vedle sebe ještě neviděl použít.
pravidlo f
Zdá se mi divné… Vyčleňovat třeba Routery kvůli tomu, že je jich hodně? Dává mi větší smysl prohlásit celé routování za samostatný celek a dát do něj všechno, co s ním souvisí. Např. Nette\Application\Routing\IRouter, ono toho víc nebude.
Neměl bych problém ani s namespacem Nette\Routing, které by odpovídalo i pravidlu d.
- Nilp
- Člen | 65
Katalogizace je skvělá, navrhuji ještě jmenné prostory
Exception
, zvláště Nette\
by to
prospělo. Dále:
Templates\PhpFilesStorage
→Templates\PhpFileStorage
?Application\UI\PresenterLink
→Application\UI\Link
? (bude tam ještě nějaký další?)Application\UI\AppForm
→Application\UI\Form
Editoval Nilp (5. 4. 2011 11:00)
- Vojtěch Dobeš
- Gold Partner | 1316
PhpFileStorage
do Templates
patří, protože je
implementací cachování šablon, ne? Viz původní název té třídy.
- David Grudl
- Nette Core | 8218
Předně: nechtěl bych tu startovat další nikamnevedoucíflame, takže prosím pište jen připomínky, které považujete za skutečně podstatné.
Lopo napsal(a):
celkom by ma zaujimal dovod zrusenia ArgumentOutOfRangeException – kedze to mam pouzite v BailIff\Utils\Network::CIDR2LongRange()
Framework ji nepoužívá tudíž si ji nemusí definovat. Přesunem do prostoru Nette už jde o soukromé výjimky frameworku.
Jan Tvrdík napsal(a):
Špatně vidím, nebo skutečně chybí IPresenter a BadRequestException
Nic se na nich nemění.
Navrhuji přejmenovat AppForm na Form (v souladu s 2. pravidlem).
Form extends Form může být pro začátečníky hodně matoucí.
paranoiq napsal(a):
pořád se mi nelíbí ta přílišná katalogizace, kvůli které pak porušuješ pravidlo b) (Responses\..Response, Routers\..Router, Helpers\..Helper).
Mě taky a je to vlastně poslední věc, o které bych ještě diskutoval :-)
celé pravidlo f) považuji za špatné
Třeba v případě Nette\Database\Drivers
mi to vyloženě
vyhovuje. „Úplně“ za špatné bych to neviděl.
- Honza Marek
- Člen | 1664
David Grudl napsal(a):
paranoiq napsal(a):
pořád se mi nelíbí ta přílišná katalogizace, kvůli které pak porušuješ pravidlo b) (Responses\..Response, Routers\..Router, Helpers\..Helper).
Mě taky a je to vlastně poslední věc, o které bych ještě diskutoval :-)
Máš moje svolení zbytečně nekatalogizovat :-D
- bazo
- Člen | 620
Nilp napsal(a):
Katalogizace je skvělá, navrhuji ještě jmenné prostory
Exception
, zvláštěNette\
by to prospělo.
tiez som za pridanie namespace Nette\Exceptions\, s vynimkami pracujem celkom casto a je treba si pamatat ich nazvy ked ich chcem vylovit, takto by som len napisal Nette\Exceptions\ stlacil ctrl+medzera a dostal by som zoznam vsetkych vynimiek. Cize podporuje to pohodlie programatora :)
- xificurk
- Člen | 121
Osobně mi přijde hloupé pravidlo a), protože:
- Velmi často koliduje s doporučením b) a v předloženém seznamu změn
je jednou upřednostněna výstižnost názvu a jindy
neduplicita. Sice je pravidlo a) „jasně“ definované požadavkem
na podmět, ale to do celého problému jen vnáší další
pravidlo, které celkem nevhodně nastavuje hranici mezi a) a b).
Typickým matoucím příkladem je
Application\Responses\JsonResponse
(vítězí a) vs.Http\Response
(vítězí b) - Pokud požadujeme „třída musí mít výstižný název i bez uvedení jmenného prostoru“, tak to člověka logicky vede k otázce – „A proč teda ty jmenné prostory zavádíme?“. Jednoduše řečeno – pravidlo a) mi připadá jako zpátečnické beznamespacové myšlení.
--
Taky se přimlouvám za přejmenování AppForm. Je pravda, že Form extends Form vypadá divně, ale to je interní věc frameworku, která moc lidí trápit nebude. Důležité je, že v aplikaci se používá buď Application\Form, nebo Forms\Form. Případů, kdy je rozumné oba přístupy mixovat moc nebude, natožpak případů, kdy se oba přístupy mixují v jednom souboru.
Editoval xificurk (7. 4. 2011 17:23)
- paranoiq
- Člen | 392
David: Třeba v případě Nette\Database\Drivers mi to vyloženě vyhovuje
ale vždyť jde o stejný případ. čím se Drivers\..Driver liší od příkladů výše? (Reflection\..Reflection a Selector\..Selection sice není úplně to samé, ale také se mi to moc nezdá :/)
pokud se ti
Responses\..Response, Routers\..Router, Helpers\..Helper
nelíbí a
Drivers\..Driver
ano, chceš to udělat nekonzistentně? já
myslím katalogizovat buď všude nebo nikde. (a jsem pro druhou
možnost ;)
xificurk
jméno třídy se většinou v kódu vyskytuje bez NS, protože
use
. proto musí být poznat o co jde ze samotného názvu
třídy. jinak se zhorší čitelnost kódu. pravidlo a) je setsakra
užitečné
xificurk & Jan Tvrdík
nováčci jistě uvítají, že Nette obsahuje dvě funkčně odlišné třídy Form ;->
Nette\Finder → Nette\FileFinder
souhlasím. finder je nic neříkající jméno
- Majkl578
- Moderator | 1364
Souhlasím s návrhem na Nette\Exceptions
.
Jsem i pro přejmenování AppForm
→ Form
.
Argument class Form extends Form
stojí za prd, protože to není
reálné kvůli kolizi a i framework by musel použít něco jako
class Form extends Nette\Forms\Form
. A asi nikdy jsem neviděl
použití AppForm
a Form zároveň, upřímně, kdo
z vás ano?
Context
, Request
a IResponse
porušují pravidla a) a c):
Nette\Application\DI\Context
vs.Nette\Http\Context
Nette\Application\Request
vs.Nette\Http\Request
Nette\Application\IResponse
vs.Nette\Http\IResponse
(Pravidlo a) mi mimochodem přijde jako krok zpět, viz co psal xificurk. Máme tu přece
as
uuse
, ne?)
Některé další třídy porušují pravidlo a) (tj. bezu uvedení namespace):
Nette\Diagnostics\Helpers
– helper čeho / k čemu?Nette\Latte\Filter
– filter čeho?
Přejmenování HttpUploadedFile
na
Nette\Http\FileUpload
mi přijde hodně WTF, protože
FileUpload
evokuje spíš prostředek k nahrávání souborů,
rozhodně ne nahratý soubor. Raději bych volil
Nette\Http\UploadedFile
.
Nekonzistence jmen tříd v Nette\Application\Responses
–
některé mají -ingový tvar, některé ne. Nechat nekonzistentní nebo
sjednotit? (Download
× Downloading
,
Render
× Rendering
)
Třídy jako String
, Image
apod. bych nasypal do
prostoru Nette\Utils
.
Mimochodem, nepasovaly by třídy IUser
& User
lépe do Nette\Application (Nette\Web\User
→
Nette\Application\User
)?
- Filip Procházka
- Moderator | 4668
Myslím že pravidlo a) by mělo mít větší prioritu než duplicity v názvu.
Editoval HosipLan (5. 4. 2011 15:05)
- xificurk
- Člen | 121
paranoiq napsal(a):
jméno třídy se většinou v kódu vyskytuje bez NS, protožeuse
. proto musí být poznat o co jde ze samotného názvu třídy. jinak se zhorší čitelnost kódu. pravidlo a) je setsakra užitečné
To není obecně pravda, tohle přeci záleží na volbě programátora.
Stejně jako např. u pojmenování proměnných je jen na něm, aby našel
kompromis mezi srozumitelností a leností psát. Pokud si
jsem jistý, že to bude srozumitelné použiju
use Nette\Http\Request;
, pokud hrozí nějaké zmatení tak
použiju use Nette\Http;
a v kódu se pak odkazuji na
Http\Request
.
- Majkl578
- Moderator | 1364
gmvasek napsal(a):
Ad použití Form + AppForm dohromady – nejspíš jsem ještě naučený z PHP 5.2 verzí, nicméně validační pravidla připisuji přes
Form::SOMETHING
.
A kde je problém? Však to by fungovalo úplně stejně jako doposud…
(Mmj. v PHP 5.3 můžeš použít i přístup ke konstantě přes instanci:
$form::INTEGER
.)
- Honza Marek
- Člen | 1664
Když už teda hlasujeme o prioritách, tak hlasuju pro nízkou prioritu pravidla a :)
- Patrik Votoček
- Člen | 2221
Vyhnu se zbytečnému flame okolo všecho a vypíchnu jenom jednu věc a to
AppForm
vs Form
. Předně jsem pro
přejmenovat AppForm
na Form
. Kdo z vás kdy
naposledy použil samotný Nette\Forms\Form
? Podle mě ho
používají pouze lidé kteří používají samotné formuláře. Takže to
tak matoucí není.
Nehledě na:
varianta 1 (ta kterou nemám rád):
namespace App;
use Nette\Application\AppForm;
class FooPresenter extends BasePresenter
{
protected function createComponentMyForm($name)
{
$form = new AppForm($this, $name);
$form->addText('foo', "Foo")->addRule(AppForm::PATTERN, "[a-z0-9]");
}
}
varianta 2 (hezčí srozumitelnější ale používám 2 různé „Form“):
namespace App;
use Nette\Forms\Form,
Nette\Application\AppForm;
class FooPresenter extends BasePresenter
{
protected function createComponentMyForm($name)
{
$form = new AppForm($this, $name);
$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
}
}
varianta 3 (po přejmenování Nette\Application\AppForm
na
Nette\Application\Form
):
namespace App;
use Nette\Application\Form;
class FooPresenter extends BasePresenter
{
protected function createComponentMyForm($name)
{
$form = new Form($this, $name);
$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
}
}
Aneb ve variantě 1 definuju pravidlo PATTERN ale musím psát
AppForm
proto si to ve variantě 2 usnadním a přidám
use Nette\Forms\Form
abych mohl psát jenom Form
(tím
ale vznikne trochu WTF proč instancuju AppForm
když pro pravidla
používám Form
). No a varianta 3 je prostě žůžo labůžo…
No ni?
Jó a jednu tak trochu „OFF TOPIC“ si neodpustím a to co
App
namespace pro sandbox?
- Jan Jakeš
- Člen | 177
AppForm
→Form
+1Nette\Exceptions
+1App
namespace pro sandbox → navrhuji pro používání namespace uvnitř aplikace lehce přizpůsobit defaultní implementaciPresenterFactory
https://forum.nette.org/…itr-aplikace
- kravčo
- Člen | 721
Patrik Votoček napsal(a):
varianta 1 (ta kterou nemám rád):
…
varianta 2 (hezčí srozumitelnější ale používám 2 různé „Form“):
…
variant 3
namespace NetteSandbox;
use Nette\Application\AppForm as Form;
class FooPresenter extends BasePresenter
{
protected function createComponentMyForm($name)
{
$form = new Form($this, $name);
$form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]");
}
}
David Grudl napsal(a):
a) Název každé třídy i bez jmenného prostoru musí vystihovat její podstatu, tj. název musí obsahovat podmět.
Pravidlo a) neznamená, že názov triedy musí byť jednoznačný v rámci frameworku.
Mne sa veľmi páči zápis
<?php
use Nette\Http;
$request = new Http\Request;
$response = new Http\Response;
pretože krásne využíva vlastnosť PHP „importovať“ menné priestory. Analógia z aktuálneho stavu je zbytočne ukecaná:
<?php
use Nette\Http\HttpRequest,
Nette\Http\HttpResponse;
$request = new HttpRequest;
$response = new HttpResponse;
Škoda len, že nie všetky triedy sa dajú takto zapísať…
- na1k
- Člen | 288
kravčo napsal(a):
variant 3namespace NetteSandbox; use Nette\Application\AppForm as Form; class FooPresenter extends BasePresenter { protected function createComponentMyForm($name) { $form = new Form($this, $name); $form->addText('foo', "Foo")->addRule(Form::PATTERN, "[a-z0-9]"); } }
Používat jako alias jméno nějaké jiné třídy je trochu masochismus, ne?
…
Asi bych byl taky za přejmenování AppForm
na normální
Form
(a přesun někam do Application
) a nahrazení
obyč Form
u něčím jiným. Form
využijí jen ti co
používají standalone formuláře; těch je ale minimum. Zatímco většina
jede na plné verzi Nette a musejí psát o tři znaky delší
AppForm
. Já hlasuji pro pohodlí většiny :)
- Patrik Votoček
- Člen | 2221
kravčo napsal(a):
David Grudl napsal(a):
a) Název každé třídy i bez jmenného prostoru musí vystihovat její podstatu, tj. název musí obsahovat podmět.
Jinými slovy, nemělo by být nutné používat AS
v klauzuli USE.
na1k napsal(a):
Asi bych byl taky za přejmenování
AppForm
na normálníForm
(a přesun někam doApplication
) a nahrazení obyčForm
u něčím jiným.Form
využijí jen ti co používají standalone formuláře; těch je ale minimum. Zatímco většina jede na plné verzi Nette a musejí psát o tři znaky delšíAppForm
. Já hlasuji pro pohodlí většiny :)
Souhlas
- David Grudl
- Nette Core | 8218
Přátelé, alespoň většina z vás, ten post jsem psal tak tři hodiny, kdybyste věnovali alespoň 15 minut snaze ho přečíst a pochopit, dalo by se tu i o něčem diskutovat.
- Patrik Votoček
- Člen | 2221
Já ho četl a to 2x… :-/
Nechme tedy AppForm stranou možná se to ztratilo v kontextu ale co
App
namespace pro „sandbox“ / „app“?
- David Grudl
- Nette Core | 8218
paranoiq napsal(a):
David: Třeba v případě Nette\Database\Drivers mi to vyloženě vyhovuje
ale vždyť jde o stejný případ. čím se Drivers\..Driver liší od příkladů výše?
Nevadí to proto, že instanci nikdy nevytváříš a je to výhodné proto,
že se tak lépe řeší dynamické instancování
("Drivers/{$name}Driver"
).
Majkl578 napsal(a):
Některé další třídy porušují pravidlo a)
Nette\Latte\Filter
– filter čeho?
Doporučuji nastudovat význam slova podmět / podstatné jméno ;-)
Přejmenování
HttpUploadedFile
naNette\Http\FileUpload
mi přijde hodně WTF, protožeFileUpload
evokuje spíš prostředek k nahrávání souborů, rozhodně ne nahratý soubor.
Přesně tak, jestli došlo k nahrání se zjistí až přes isOk().
Nekonzistence jmen tříd v
Nette\Application\Responses
– některé mají -ingový tvar, některé ne. Nechat nekonzistentní nebo sjednotit? (Download
×Downloading
,Render
×Rendering
)
Jj, upravím na neingový tvar.
xificurk napsal(a):
Pokud si jsem jistý, že to bude srozumitelné použiju
use Nette\Http\Request;
, pokud hrozí nějaké zmatení tak použijuuse Nette\Http;
a v kódu se pak odkazuji naHttp\Request
.
A kdy použiješ Json
nebo File
?
- David Grudl
- Nette Core | 8218
O pravidle a) prosím vůbec nediskutujme, to je naprosto základní pilíř celé koncepce.
- David Grudl
- Nette Core | 8218
Sdružující jmenné prostory Iterators, Responses, Routers a Helpers jsem zrušil.
- Jan Tvrdík
- Nette guru | 2595
David Grudl wrote: A zase si to rozmyslel a vrátil je.
:P
Nette\Database\Drivers
aNette\Iterators
se mi libí.- Naopak jsem proti
Nette\Exceptions
(viz také RFC). - U
Nette\Application\Routers
mi vadí, že neobsahuje rozhraníNette\Application\IRouter
(tj. shlukuje to routery a ne celou problematikou routování). Proč? Nette\Template\Helpers
mi je v celku jedno. Záleží na tom, jestli v budoucnu předpokládáš, že tam toho bude víc.- Na
Nette\Application\Responses
nemám jednoznačný názor. - Stále si myslím, že
AppForm
by se měl přejmenovat naForm
, ale v nejhorším si to pořeším sám v aplikaci.
- juzna.cz
- Člen | 248
Vyjimky bez namespace se mi libi. Jelikoz je potencialni problemy potreba osetrovat neustale, a kazdou chvili nejake jine, tak v kazdem souboru nekolik trid vyjimek mit budu. Pred zavedenim namespace bylo jejich pouziti snadne; s namespace se pak pridal jen jeden znak – zpetne lomitko.
Jak budete resit vyjimky kdyz budou namespacovane? Pomoci use + nekolik trid jen pro vyjimky v kazdem souboru? Nebo budete psat cele jmeno? Me to prijde docela dost psani navic :(
- Pavel Kouřil
- Člen | 128
S Nette\Exceptions souhlasím – už jen díky tomu, že si člověk pak napíše jen Exceptions\ a dá ctrl-shift a vyjedou mu všechny možné Nette výjimky (což se hodí, protože každá výjimka začíná jiným slovem než Exception; a hledat nějakou konkrétní by bylo poměrně otravné, když si člověk nepomatuje její název zpaměti).
- Jan Tvrdík
- Nette guru | 2595
Jsem toho názoru, že aplikace by neměla používat
výjimky z jmenného prostoru Nette
. Aplikace by měla být
ideálně celá obalena vlastním
jmenným prostorem a v něm si definovat vlastní výjimky (které by
neměly dědit od výjimek z jmenného prostoru
Nette
).
- Filip Procházka
- Moderator | 4668
Honzo, s těmi výjimkami máš samozřejmě pravdu, ale né všichni
vědí, že by měli psát výjimku zvlášť pro každou třídu/balíček,
nebo to chtějí dodržovat. Já to dodržuji jen částečně. Rozhodně jsem
pro zabalení Nette výjimek do Exceptions\
, je to neuvěřitelně
pohodlné.
David Grudl napsal(a):
A zase si to rozmyslel a vrátil je.
Jsem pro Nette\Application\Responses\ForwardingResponse
. Sám to
používám, když mám skupinu tříd, které dělají podobnou činnost
(responses, Iterators, …).
Editoval HosipLan (7. 4. 2011 7:59)
- David Grudl
- Nette Core | 8218
Jsem pro
Nette\Application\Responses\ForwardingResponse
. Sám to používám, když mám skupinu tříd, které dělají podobnou činnost (responses, Iterators, …).
Jsem pro Nette\Application\Responses\Forward
:-)
- Filip Procházka
- Moderator | 4668
Jsi si jistý, že to dostatečně popisuje co třída dělá? :) Možná u forward ano, ale co takový Json?