Mam model prawie 1k lini kodu.
20 validacji, 10 assocjacji, 40 named scopów, dekoratory, aftery befory, ze 40 prywatnych itp
Chcę to porozbijać na mniejsze pliki. Czym się kierować przy podziale i nazywaniu plików/modułów ?
Mogę gdzieś podglądnąć dobre praktyki takiego refaktoringu. Jak to u Was wygląda?
Jakkolwiek porozbijasz na mniejsze pliki to wciąż będą tylko mniejsze pliki prawda ? Ta klasa pewnie ma za dużo odpowiedzialności i trzeba rozbić na mniejsze. Andrzej Krzywda kiedyś pokazał na wykładzie fajny trik. 2 klasy do jednej tabeli. Akurat miał przykład w którym to było bardzo sensowne. Elementy koszyka i elementy zamówienia.
[code]class Foo
set_table_name :table_name
end
class Bar
set_table_name :table_name
end[/code]
Może na początek mogłoby pomóc, a może nie. To tylko technika, use at your own risk.
Ogólnie ja bym szedł w stronę rozbijania, wyciągania jej odpowiedzialności niż tylko rozdzielania plików.
[quote=paneq]Jakkolwiek porozbijasz na mniejsze pliki to wciąż będą tylko mniejsze pliki prawda ? Ta klasa pewnie ma za dużo odpowiedzialności i trzeba rozbić na mniejsze. Andrzej Krzywda kiedyś pokazał na wykładzie fajny trik. 2 klasy do jednej tabeli. Akurat miał przykład w którym to było bardzo sensowne. Elementy koszyka i elementy zamówienia.
[code]class Foo
set_table_name :table_name
end
class Bar
set_table_name :table_name
end[/code]
Może na początek mogłoby pomóc, a może nie. To tylko technika, use at your own risk.
Ogólnie ja bym szedł w stronę rozbijania, wyciągania jej odpowiedzialności niż tylko rozdzielania plików.[/quote]
To nie musi być sensowne w większości przypadków. Byłbym bardzo ostrożny i nie rzucał się na refaktoryzację wszystkiego w ten sposób.
Możesz sprówać konkretne funkcjonalnoći przenieść do modułów znajdujących się np. w podkatalogu a następnie je includować.
Przykład: Jeśli decydujemy się, że nasz model ma dedykowany (własnego autorstwa) mechanizm stanów (state machine) to można to wrzucić do oddzielnego modułu.
[quote=wafcio]Możesz sprówać konkretne funkcjonalnoći przenieść do modułów znajdujących się np. w podkatalogu a następnie je includować.
Przykład: Jeśli decydujemy się, że nasz model ma dedykowany (własnego autorstwa) mechanizm stanów (state machine) to można to wrzucić do oddzielnego modułu.[/quote]
To też tylko rozbije kod na mniejsze pliki, ale końcowo będziesz miał prawie to samo (a nawet gorzej, bo część rzeczy trzeba będzie zrobić w metodzie “included” jako, że to już nie będzie klasa).
Myślę, że odpowiedź na to pytanie jest ciężka, bo wszystko zależy od tego co w tych modelach tak naprawdę jest. W większości wypadków, żeby takie refaktoryzacje miały sens, trzeba to dobrze przemyśleć, a rozwiązania nie są trywialne, tzn. nie ma jakiegoś wzorca tego czy rozpakować jakiś kawałek do zewnętrznego pluginu przy okazji odrywając kod od aplikacji, czy wypakować np. zawartość jakiejś metody do innej klasy i zostawić w aplikacji.
Kolega ktory robil update z 3.0 do 3.1 mial duze klopoty z tym pluginem. Skonczylo sie tak ze zaczal uzywac modulow aby osiagnac to samo. Dla mnie ten gem to slaby hack
Moduły sprawdzają się tylko i wyłącznie do współdzielenia funkcjonalności pomiędzy różnymi klasami, możesz sobie “wmiksować” pewien zestaw metod do jednej, drugiej i trzeciej klasy, nie używając wspólnej klasy bazowej.
Moduły nie rozwiążą problemu przerostu ilości kodu w pojedynczej klasie, tylko ten problem zafałszują. Niestety to trudny problem do sensownego rozwiązania, szczególnie w przypadku ActiveRecord.
A taki prosty przykład… Spasły model ma 10 validacji railsowych i 10 validacji moimi metodami. Chcę to wyekstrachować do innego pliku.
Do modułu pomimo iż tego kodu nie użyje w żadnej innej klasie czy otwarcie klasy w innym pliku i wklepanie tam kodu? Podobnie ze scopami…
Pewnie przetestuje obie wersje i zobacze co wygodniej i ładniej ale chciałbym poznać opinie bardzie doświadczonych kolegów.
+1 do tego co napisał Hubert. Tak jak pisałem powyżej “now you have 2 problems”.
Tak jak już pisałem na początku, każde rozwiązanie, które nie zmienia samej struktury kodu, tylko rozrzuca go w wielu miejscach niewiele pomoże. Być może dla niektórych inspiracją do takiego działania jest to co ostatnio było robione w railsach, szczególnie w ActiveRecord, tzn. kod był właśnie rozrzucony po dużej ilości modułów. Tam ma to troszeczkę większy sens, bo to jest framework. W przypadku AR nie ma to tak dużego sensu jak np. w ActionControllerze, bo jest bardzo duża szansa, że ktoś w aplikacji będzie chciał lekki kontroler np. bez obsługi cookies, a szansa na to, że ktoś sobie zbuduje własną klasę bazową do modeli jest bliska zeru, ale dalej to jest trochę inna skala problemu.
Pomyśl o tym w ten sposób: mam wielką klasę na 2000 linii, dlatego ciężko mi ją testować i połapać się we wszystkich metodach. Teraz zamieniasz tą klasę na 5 różnych plików, w których jest dokładnie ten sam kod (no… w przypadku modułów prawie ten sam, ale w tym wypadku prawie nie robi dużej różnicy). Czy nagle jest Ci łatwiej się połapać o co chodzi? Czy łatwiej jest to testować?
Zgadzam się. Ale można do tego podejść jak do trzymania plików folderach. Łatwiej się połapać, znaleźć coś jeżeli masz dobrze nazwane foldery i w nich odpowiednie pliki. Ale łapię przekaz, inaczej podejdę do refaktoringu.