Mam dosyć sztywnego trzymania się niektórych zasad dobrego stylu
programowania. Pisząc CJC starałem się
w ogóle nie używać zmiennych globalnych, bo przecież każdy wie, że tak trzeba.
No i dało się, jednak z tak zrobionego kodu nie byłem zadowolony. Mam tam
takie trzy obiekty, właściwie singletony, do których dostęp potrzebny był
w bardzo wielu miejscach. No i dostęp ten odbywał się właściwie na dwa
sposoby: albo referencja do takiego obiektu była przekazywana w konstruktorze i potem
zapisywana w atrybucie obiektu który tego potrzebował, albo dostęp odbywał się
przez inne obiekty (np.:
) –self.plugin.app.screen
jedno i drugie nie wyglądały najlepiej. Standardowym, Javowe
,
rozwiązanie, w postaci statycznej metody zwracającej instancję singletona,
niespecjalnie mi pasowało – to takie niepythonowe odwoływać się do
klasy, gdy tylko jej instancja jest potrzebna. Do tego to więcej pisania by
było, a przecież miałem API uprościć.
W końcu zdecydowałem się na rozwiązanie proste i skuteczne –
zrobiłem moduł cjc_globals
z trzema zmiennymi globalnymi. I wszystko
byłoby dobrze, gdyby nie komunikat przy commicie, wyraźnie sugerujący, że
za moją decyzją stoi Zło: Committed revision 666.
;-)
A co będzie dalej? Używanie GOTO? 😛
PolubieniePolubienie
By Jove!
PolubieniePolubienie
AlchemyX: hmmm… niezła myśl. Tylko muszę to całe CJC najpierw sportować na jakiś inny język, bo w tym głupim Pythonie nie ma GOTO. 😉
PolubieniePolubienie
W Zend Framework jest ciekawe rozwiązanie.
Jest klasa Registry, którą możesz poprosić o singleton, który służy do trzymania innych obiektów w haszu.
Kiedy potrzebujesz jakiś obiekt upublicznić to rejestrujesz go w Registry pod wybraną nazwą. Gdy jest Ci potrzebny to sobie z registry pobierasz "nazwaną" referencję i używasz.
PolubieniePolubienie
smk: Takie coś też będzie, ale dla mniej "fundamentalnych" obiektów. Nie chciałem robić dodatkowych "pośredników" dla trzech obiektów do których dostęp jest ciągle potrzebny — dobrze, żeby był jak najłatwiejszy.
Inne obiekty, które będą mogły być dodawane przez pluginy lub inne "luźne" komponenty będą dostępne przez jakiś rejestr. Np. obiekt realizujący archiwum wiadomości.
PolubieniePolubienie
w ruby jest fajny moduł zwany singleton, klasę piszemy normalnie, jakby nigdy nic, normalny konstruktor tyle że bez parametrów:) dopisujemy do ciała klasy `include Singleton` [po uprzednim `require ‚singleton’`] i możemy się odwoływać do instancji za pomocą metody .instance, w/w moduł sam ją implementuje [wraz z paroma innymi], wiec nie ma problemów:) mechanizm mixins w ruby jest imo na prawdę fenomenalny;-)
PolubieniePolubienie
A w Scali w samym języku mamy wbudowane Singletony.
object GlobalVariablesMisuse {
val evilVariable = 666
}
println(GlobalVariableMisuse.evilVariable)
PolubieniePolubienie