Post
#1
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Cześć, programuję w php, js, html, css, czyli taki standard jeżeli chodzi o strony www, frameworki to: laravel, vue.js, materializecss, może niektórzy mnie kojarzą po nicku.
Spotykam się czasem podczas pisania aplikacji z tym, że w pewnym momencie np. w połowie prac, uświadamiam sobie, że kod jest bardziej zawile napisany niż mógłbym być. Załóżmy, że chciałem zastosować do kilku funkcjonalności tą samą część kodu i teraz okazuje się, że, aby tą część wykorzystać, komplikuję sobie świeżo pisane rzeczy, żeby je dostosować do tego co już mam. Teraz przyszło mi na myśl, czy aż tak ważne jest to, aby nie powielać kodu, bo w sumie kierując się taką genezą, wszystko mam (tak mi się wydaje) napisane bardziej zawile, ostatecznie tylko po to, żeby wykorzystać istniejące elementy i dostosować do nich nowe. Przeważnie znajdują się jakieś mini różnice w poszczególnych funkcjonalnościach, które po zsumowaniu robią o wiele większy bałagan niż jakby napisać dla każdej funkcjonalności oddzielnie ten "uniwersalny kod". Dodatkowo, jeśli teraz chciałbym zmienić rzeczy, które są używane w kilkunastu miejscach, to te kilkanaście miejsc przestaje działać z automatu i muszę je wszystkie poprawiać. Nie wiem, czy przedstawienie sprawy w tak ogólny i teoretyczny sposób pozwoli Wam się odnieść do tematu, jeśli nie to podam jakiś przykład. Druga rzecz, to np. 5 lub więcej rozwiązań jednego problemu, gdzie większość wydaje się być niezła. Jak podejmujecie decyzje, czy na szybko, czy jakoś bardziej analizujecie, bo mi schodzi trochę czasu na takie analizy i jest to dość irytujące? Mam w sobie jakąś taką cechę, że strasznie drażni mnie jak zaczyna się robić bałagan i zależy mi bardzo na prostocie i przejrzystości tego co piszę, zarówno od strony użytkownika jak i programisty, chciałbym, żeby to co piszę było idealne i jak mi się nie udaje to mam nerwy. Czy macie podobne problemy, jeśli tak, jak sobie z nimi radzicie? Może to kwestia doświadczenia, programuję zawodowo już praktycznie 2 lata, więc trochę doświadczenia nabrałem, ale to jednak nie 10 lat:p Próbuję sobie wytworzyć jakieś standardy i rozwiązania powtarzalnych problemów, czyli np. stosować jeden lub dwa typy formularzy we froncie, na upload filmów mieć jeden sprawdzony sposób po stronie użytkownika i serwera, usuwanie zasobów też działające w konkretny sposób do wielokrotnego stosowania. Tylko teraz pytanie się pojawia, czy chcąc budować taką swoją bazę rozwiązań nie zostanę w tyle, przez to, że nie zapoznaję się z innymi narzędziami, a pracuję cały czas na tych samych, oczywiście aktualnych wersjach. Co sądzicie? |
|
|
|
![]() |
Post
#2
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
Stosuj dziedziczenie, kompozycję, SOLID i wzorce projektowe. Pisz małe funkcje, zamykaj je w klasach które mają pojedynczą odpowiedzialność. Pisz testy jednostkowe/integracyjne.
Polecam Ci przeczytać (i podumać nad) Clean Code. Jak zaczniesz ogarniać wzorce, i zobaczysz po co tak na prawdę jest singleton czy factory, oraz jakie niebezpieczeństwa się z tym niosą, to zaczniesz pisać ładniej. |
|
|
|
Post
#3
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Mrc, używam frameworka (Laravel), tam pewna stylistyka pisania jest już narzucona i pewne wzorce są wykorzystywane.
Czytałem kiedyś o różnych wzorcach i robiłem różne przykłady, ale korzystając z frameworka, mam to gotowe, więc się zapomina siłą rzeczy. Na jakich frameworkah pracowałeś i ile czasu, jeśli można wiedzieć? Mam na swoim koncie kilka większych aplikacji. Półtora roku doświadczenia w pracy z Laravel, więc to nie tego typu problemy, żeby stosować obiektowe programowanie (IMG:style_emoticons/default/tongue.gif) Mimo to dzięki za odpowiedź. Może na przykładzie: Mam multiformularze w większości widoków zasobów. Formularz jest generowany vue.jsem. Lista zasobów tak samo, więc dane dla listy muszą być w jsonie. Natomiast dane z formularza mogę przesłać w jednym polu w jsonie, albo normalnie, albo połączyć obie metody, wszystko zależy od rodzaju zasobu. Jeśli mam dane tekstowe tylko, to json jest okej, nawet kiedy mam obraz do przesłania to html 5 również umożliwia przesłanie go jsonem, ale co np. kiedy chcę przesłać pdf, lub film, wtedy muszę przy wybraniu pliku, przesłać go do tymczasowego folderu ajaxem, najlepiej wyświetlić go w formularzu i jeszcze dodać opcję usunięcia i wybrania ponownie pliku, tak dla każdej pozycji w formularzu, bo jak wspomniałem są to multiformularze. Już w tym momencie jest kilka możliwości rozwiązania tych zagadnień i załóżmy, że upload jest wykorzystywany w kilku miejscach. Zgodnie z zasadą niepowielania kodu dobrze byłoby stworzyć narzędzie (metody, widok w vue.js) do uploadu filmików i obrazów, ale później przychodzi kolejna funkcjonalność: upload kilku obrazów na raz i to po przez upuszczenie, a nie tylko wybór plików standardowy i co, modyfikować to co mamy, pod następną funkcjonalność komplikując sobie jeszcze bardziej to co i tak już dość zawiłe przez to, że obsługuje i filmy i obrazy? Cytat pojedyncza odpowiedzialność to jest chyba słowo kluczTen post edytował Omenomn 4.01.2017, 22:43:40 |
|
|
|
Post
#4
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
2 lata Zend (edit), 2 lata Kohana, rok Symfony i 3 miesiące Laravel. Framework nie jest tak ważny. Własną logikę biznesową budujesz w każdym fw. Jeżeli jej nie budujesz, to znaczy że robisz to źle. Co do wzorców, pamiętaj że np. samo stworzenie jednolinijkowej statycznej funkcji factory() nie powoduje jeszcze, że tworzysz fabrykę (dobrą fabrykę). Niestety, nawet popularne frameworki czy biblioteki mają sporo takich udziwnień.
--Edit-- Przepatrzyłem swój profil na LinkedIn. Dwa lata zenda poproszę. Ten post edytował mrc 4.01.2017, 22:21:38 |
|
|
|
Post
#5
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Zenda nie znam, na Kohanie niestety, albo stety dane mi było pracować chwilę, przynajmniej wiem jaka jest kiepska (IMG:style_emoticons/default/tongue.gif) , jak CodeIgniter lub gorzej (IMG:style_emoticons/default/tongue.gif)
Rok Symfony i 3 miesiące Laravel można porównać do mojego półtora roku na Laravel. Odnośnie tego, że framework nie jest tak ważny nie zgodzę się, wystarczy porównać Kohanę lub CodeIgnitera z Laravelem, albo Symfony - zupełnie inny poziom pisania, choćby przez composera i artisana w laravel, ale to inny temat. Ten post edytował Omenomn 4.01.2017, 22:52:02 |
|
|
|
Post
#6
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
Nie ma co porównywać doświadczeń. Moje doświadczenia są takie, że wszędzie jest jakaś logika biznesowa, o którą trzeba dbać - pisać testy, refactorować itp. Jeżeli rozmieszczasz wszystko w akcjach i klasach modelowych, to współczuję. Wtedy nie masz logiki.
|
|
|
|
Post
#7
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Umieszczam kod w miejscach uzależnionych od potrzeb, ale w ogromnej przewadze są to jednak kontrolery i modele, używam zdarzeń, middlewarów, jobsów praktycznie nigdy, bo są rzadko potrzebne, walidacji w requestach, jednak request nie zwróci mi obiektu z danymi jakie dostał plus z tablicą z errorami, dlatego mam to w kontrolerach w ostatnich projektach.
Oprócz tego są przecież widoki, tłumaczenia, są configi, migracje, seedy, to wszystko też się składa na logikę aplikacji, jest storage ogarniający pliki, composer, artisan... Moje rozterki nie są raczej banalne, ale rzeczywiście ta pojedyncza odpowiedzialność w metodach u mnie rzeczywiście trochę na bakier, muszę nad tym popracować. |
|
|
|
Post
#8
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
Stosuj wyżej podane techniki, a na pewno polepszy się Twój ogólny proces programowania. Do tego staraj się nazywać zmienne lepiej, nie komentuj rzeczy, które w oczywisty sposób wychodzą z kodu. W ogóle, to wszystko co mówię - to jest napisane w Clean Code. Ta książka zmieniła moje postrzeganie kodu, odkąd ją zrozumiałem (!= przeczytałem) nie mam problemów z czytelnością kodu.
|
|
|
|
Post
#9
|
|
|
Grupa: Zarejestrowani Postów: 419 Pomógł: 5 Dołączył: 7.08.2012 Ostrzeżenie: (0%)
|
dzięki za informację
Cytat dochodzi do tego jeszcze odpoczynek (dużo odpoczynku) |
|
|
|
Post
#10
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
+1 ZenekN
Do odpoczynku dochodzi uprawianie sportu, życie poza komputerem, wychodzenie z domu i wiele innych, które sprawiają że jesteś świeży. |
|
|
|
Post
#11
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Okej mrc, zastanawia mnie tylko dlaczego wychodzisz z założenia, że ich nie stosuję, przynajmniej zdecydowanej większości.
|
|
|
|
Post
#12
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
Bo te techniki zapobiegają problemom z nieczytelnym i skomplikowanym kodem - a Ty z tym masz problem. Ok, może źle mówię, może stosujesz (tego nie wiem) - ale coś w takim razie idzie Ci z tym nie tak jak potrzeba.
|
|
|
|
Post
#13
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Sądzę, że większość programistów ma z tym problem nie tylko Ja, są tego może mniej świadomi, miałem do czynienia z kodem różnych ludzi, nawet z większym doświadczeniem od siebie i to chyba oczywiste, nie był idealny.
Dobra ogarnę książkę o czystym kodzie, ale wątpię, że będzie do zastosowania z niej wiele rzeczy na frameworku, obym się mylił, zobaczymy. Ten post edytował Omenomn 5.01.2017, 11:07:40 |
|
|
|
Post
#14
|
|
|
Grupa: Zarejestrowani Postów: 419 Pomógł: 5 Dołączył: 7.08.2012 Ostrzeżenie: (0%)
|
Ogólnie mam podobny problem ale chyba dlatego że jestem dość roztargniony i nie podchodzę do tematu tak jak potrzeba.
Prosta odpowiedź Cytat Doświadczenie + nauka = doskonałość kodu Miałem problem o którym pisałem na forum (jestem samoukiem) zleciłem projekt dobremu programiście na początku byłem zachwycony tym człowiekiem myślałem że jest świetnym programistą. Tylko pamiętam ciągle słowa "Nie będę ciągle wprowadzał poprawek" czyli że coś było ciągle ze mną nie tak, Po kilku latach nauki z mojej strony kiedy już znacznie rozumiem wzorce A wystarczyło wprowadzić prawidłowo relacje w bazie danych np.(n:n) i voila problem rozwiązany. Czyli tak jak autor wyżej napisał wracajmy do wzorców i analizujmy je krok po kroku Ten post edytował ZenekN 5.01.2017, 11:52:15 |
|
|
|
Post
#15
|
|
|
Grupa: Moderatorzy Postów: 36 561 Pomógł: 6315 Dołączył: 27.12.2004 |
@mrc mowisz o tej ksiazce?
http://ricardogeek.com/docs/clean_code.pdf |
|
|
|
Post
#16
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
@nospor
Tak, ta książka. Osobiście, wolę drukowaną wersję (IMG:style_emoticons/default/smile.gif) I niebiesko-czarną okładkę (IMG:style_emoticons/default/tongue.gif) |
|
|
|
Post
#17
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Teraz mam np. problem tego typu, że w systemie, nad którym pracuję, jest kilka zasobów wykorzystujących obrazy i filmy.
Przykładowo: 1. Slider - upload filmów z wyborem miniaturki z filmu, - obrazy również z miniaturkami. 2. Galeria - obrazy z miniaturkami. 3. Klipy - upload filmów z wyborem miniaturki z filmu, Zrobiłem to na zasadzie takiej, że każdy zasób, nazwy swoich plików przechowuje we wlasnej tabeli i teraz zastanawiam się, czy nie było by lepiej zrobić dla każdego rodzaju pliku oddzielną tabelę, a w tabelach zasobów przechowywać tylko referencje, wtedy miałbym tylko jeden model od filmów i nie musiałbym ogarniać obsługi plików filmów w sensie uploadu, czy usuwania w kilku miejscach. Natomiast minus jest taki, że przy wprowadzeniu np. 10 slidów jednocześnie, najpierw muszę dodać filmy do tabeli z filmami, obrazy do tabeli z obrazami, później dopiero wprowadzać same slidy z odpowiednimi referencjami. (IMG:style_emoticons/default/questionmark.gif) Ten post edytował Omenomn 5.01.2017, 17:42:39 |
|
|
|
Post
#18
|
|
|
Grupa: Zarejestrowani Postów: 2 592 Pomógł: 445 Dołączył: 12.03.2007 Ostrzeżenie: (0%)
|
Nie jest trochę tak, że szukasz rozwiązania na problemy implementacyjne?
Przykłady, które podałeś nie są raczej przypadkami natury warsztatu, architektury etc. Tylko bardziej szukanie rozwiązań konkretnych zagadnień, a tych w programowaniu może być bardzo dużo. Przy tym wiele z nich będzie poprawnych, nie będzie jednego najlepszego. Ten post edytował vokiel 5.01.2017, 23:06:59 |
|
|
|
Post
#19
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Właśnie o to mi chodzi, że to moje problemy nie dotyczą tylko warsztatu, a sięgają trochę głębiej, niemniej jednak pozycja http://helion.pl/ksiazki/czysty-kod-podrec...rtin,czykov.htm sądzę, że się przyda i odświeżenie sobie wzorców też.
Pracując na frameworku całą strukturę mam gotową praktycznie. Korzystam z wzorców, nie tworząc ich, przez co zapominam jak działają. Kiedyś uczyłem się o wzorcach analizując dokładnie przykłady z książki, a na dzień dzisiejszy ta wiedza jakby wyparowała (IMG:style_emoticons/default/ohmy.gif) . Wychodzi na to, że ta na nauka, była stylu, zakuć, zdać, zapomnieć, a nie cierpię się tak uczyć. Wiele bardziej wolę zapamiętywać w trakcie używania. http://helion.pl/ksiazki/php-wzorce-projek...ders,phpwzo.htm Ten tytuł sobie również przestudiuję, zobaczymy co przyniesie. Ten post edytował Omenomn 6.01.2017, 10:09:01 |
|
|
|
Post
#20
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
Omenomn może ucz się tak: dowiedz się, czym jest fasada, i zacznij w swoim projekcie (projektach) szukać miejsca, gdzie fasadę można wstawić. Rób refactory i wstawiaj fasady. Później poczytaj czym są fabryki i zastanów się, gdzie u siebie możesz takie fabryki wstawiać.
Oczywiście, do tego trzeba mieć logikę biznesową - zestawy klas które realizują algorytmy, połączenia z bazą czy innymi elementami jak np. curl, guzzle, websockety, systemy kolejkowe. |
|
|
|
Post
#21
|
|
|
Grupa: Zarejestrowani Postów: 1 332 Pomógł: 294 Dołączył: 12.10.2008 Skąd: Olkusz Ostrzeżenie: (0%)
|
z góry przepraszam za lekki spam, ale z tematu pod KOD zajebiście podchodzi ;D
zabrakło mi doświadczenia i ostrożności - oby i Tobie nie zabrakło doświadczenia i ostrożności ;D |
|
|
|
Post
#22
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
Nie ma idealnego kodu, ale za to jest Refaktoryzacja. Magiczne i jakże przydatne słowo. Polecam. I nie na uraaaa za wszystko się brać, tylko małymi kroczkami powoli, do przodu.
|
|
|
|
Post
#23
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Omenomn
Pierwsze co zrób to zapomnij o frameworku. Nie ważne czy używasz Laravela, Zenda, Symfony, to tylko baza dla resposne i request i tam się sprawdza, ale nie jako logika biznesowa. Twój model biznesowy, który powinieneś poznać zanim tak naprawdę zabierzesz się za tworzenie czegokolwiek, nie zależy od języka programowania, a tym bardziej o jakieś wymyślonej w nim implementacji w postaci Frameworka. Myślenie skoro gość X od fw y robi to tak to ja tez mogę, jest bardzo zgubne. Nie da się stworzyć gotowca na tyle uniwersalnego, żeby dla każdego problemu jaki istnieje dało się w nim stworzyć najlepsze rozwiązanie. Uniwersalne są tylko wzorce projektowe. Dlatego analizując Twój przypadek z dużym prawdopodobieństwem mogę stwierdzić, że zacząłeś typowo, mam do zrobienia projekt X, no to stawiam nowa instancje Laravela, potem co, pewnie baza danych. Po tygodniu/ miesiącu, okazuje się ze czegoś zapomniałeś nie uwzględniłeś, bazę trzeba zmienić i pól kodu. No i pojawiają się takie problemy jak tym masz, a wszystko przez to, że zacząłeś od złej strony. Zanim napisałeś pierwsza linijkę kodu powinieneś poznać swój model domenowy, jak już go poznasz to dopiero wtedy do niego dobierać odpowiednie narzędzia które pozwolą Ci go stworzyć łatwiej, a nie na odwrót. Wtedy dostrzeżesz znacznie więcej, kod będzie dużo bardziej czysty i reuzywalny niż wcześniej. |
|
|
|
Post
#24
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Sądzę, że umniejszasz trochę frameworkom jednak.
Już wymyśliłem jak ogarnąć to uploadowanie, żeby miało sens i wykorzystałem wzorzec dekorator do tego. Przykładowe przesłanie pliku wygląda tak:
1. Property - pobieranie właściwości pliku (nazwa, path, rozszerzenie). 2. ContentImage - pobiera treść pliku. 3. Thumbnail - pomniejsza treść. 4. Encode - określa rozszerzenie. 5. File - tworzy plik. Tylko mam teraz taki problem, że chciałbym w każdym z tych obiektów mieć dostęp do właściwości pobranych w obiekcie Property i nie mam pomysłu dobrego jak to zrobić. Encode potrzebuje rozszerzenie, File potrzebuje nazwę pliku, ContentImage wymaga ścieżkę. Mógłbym przekazywać właściwości dalej w każdym wywołanym obiekcie:
jednak to trochę powielanie kodu, mam parę pomysłów, ale żaden jakiś specjalny, a Wy? Spróbuję się wspomóc obserwatorem. Ten post edytował Omenomn 9.01.2017, 19:04:35 |
|
|
|
Post
#25
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Sądzę, że umniejszasz trochę frameworkom jednak. Nie, framework to tylko narzędzie coś jak IDE, i tak samo jak one może być lepsze lub gorsze, ale to tylko narzędzie ułatwiające prace, nie sprawi, że kod się sam napisze i będzie dobrej jakości. Cytat wykorzystałem wzorzec dekorator Jesteś pewny, że dobrze go zrozumiałeś? https://github.com/domnikl/DesignPatternsPH...tural/Decorator |
|
|
|
Post
#26
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Cytat Jesteś pewny, że dobrze go zrozumiałeś? Tak, a według Ciebie nie? http://blogophp.com/2009/08/16/dekorator/#more-40 http://stackoverflow.com/questions/1234554...e-re-sizing-etc Cytat Nie, framework to tylko narzędzie coś jak IDE, i tak samo jak one może być lepsze lub gorsze, ale to tylko narzędzie ułatwiające prace, nie sprawi, że kod się sam napisze i będzie dobrej jakości. Tylko, żeby nauczyć się dobrych praktyk na frameworku potrzeba kupę czasu. Jak ktoś jest oblatany w jednym to nie siądzie na inny i po dwóch miesiącach nie będzie w nim wymiatał, na poznanie frameworka i różnych w nim patentów trzeba czasu. Framework to nie tylko narzędzie, to w pewnym stopniu narzucona struktura i pewne podejście do programowania. |
|
|
|
Post
#27
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
Dekotator tutaj jest definitywnie złym rozwiązaniem skoro obiekty potrzebują zależności z innych dekoratorów.
Dekoratorem może być tutaj tylko Thumbnail bo on faktycznie coś tam robi na źródłowych danych. |
|
|
|
Post
#28
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Dobrym rozwiązaniem jest, do przekazywania atrybutów wykorzystałem obserwator, więc mam kombo dekorator-obserwator i jestem Hardkorem (IMG:style_emoticons/default/biggrin.gif)
|
|
|
|
Post
#29
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
Omenomn, skoro coś Ci w decoratorze nie pasuje, to znaczy że nie jest to dobre rozwiązanie.
Co do frameworków. Możesz być specjalistą w Laravel i 5 lat tłuc jego dobre praktyki. W pomiędzy czasie świat się zmieni. Laravel przestanie mieć większość udziałów na rynku. Będziesz miał problemy w znalezieniu pracy, bo umiesz pisać tylko tak jak uczył Laravel. Moim zdaniem programista to osoba, która nie przyzwyczaja się do rozwiązań, ma otwarty umysł na nowe/inne technologie, języki. Tak jak wyżej koledzy pisali, fw to tylko fw. Request-Response + MVC. Tak samo, jak PHP to tylko PHP i może się okazać, że za kilka lat będzie trzeba się przebranżowić, albo chociażby zmienić języki. Co wtedy? |
|
|
|
Post
#30
|
|
|
Grupa: Zarejestrowani Postów: 1 885 Pomógł: 231 Dołączył: 20.03.2005 Skąd: Będzin Ostrzeżenie: (0%)
|
10 lat temu ktoś powiedział, że trzeba porzucić PHP, bo z tego języka już nic nie będzie.
|
|
|
|
Post
#31
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Dekorator to dobre rozwiązanie, ale nie wystarczające, więc musiałem je połączyć z innym.
Swoją drogą zadanie dla Was. Jak we wzorcu dekorator przekazywać pomiędzy obiektami atrybuty elementu dekorowanego, tak, żeby każda klasa miała do nich dostęp i mogła je modyfikować i, żeby każdy obiekt widział te zmiany.
Powiem Ci tak, jeśli pracujesz na Symfony, albo Laravel, przesiądź się na CodeIgnitera, albo Kochane i zacznij pisać takie same systemy. Jeżeli nie sprawia Ci to różnicy, to okej, nie wszystkim musi zależeć na jakości pracy, ale jeśli komuś zależy to rękami i nogami będzie się bronił przed taką przesiadką, więc to nie tylko narzędzie request-response + mvc, bo configi, routing, seedy, migracje, storage, env, blade, eventy, jobsy, composer, paczki, artisan, helpery, walidacja, translatory itd. Więc zdecydowanie uproszczacie, CodeIgniter i Kochana nie ma nawet połowy z tego. Framework to owszem narzędzie, ale można używać samego młotka, albo wielu wyspecjalizowanych narzędzi, jakich dostarczają dobre frameworki.
To jest właśnie myślenie ludzi, którzy uczą się miliona rzeczy, a w żadnej nie są specjalistami. Każdy z osobna ma wpływ na rynek, jeśli zmieniasz to co lubisz na coś czego nie chcesz robić, tylko po, żeby znaleźć pracę, to dostaniesz pracę, ale się nie rozwijasz i w dłuższym czasie jesteś na minus. Ja np. nienawidzę wordpressa, bo jest zaprzeczeniem obiektowego programowania i ukazuje hipokryzję ludzką, ponieważ wszyscy mówią o obiektowym pisaniu kodu, a później jadą na wordpressie, który jest funkcyjny. Jednak jeśli lubiłbym worpressa, to śmiało mógłbym się w nim rozwijać i cisnąć cały czas, a zmienianie co 4 miesiące cmsa na joomlę, albo drupala, albo jeszcze coś innego, byłoby staniem w miejscu, bo w żadnym z tych narzędzi nie byłbym specjalistą. Jeżeli siedzi się w czymś np. 2 lata i uzna się, że już osiągnęło się poziom mastera, wtedy można zmienić framework lub narzędzie i można o sobie powiedzieć np. "jestem specjalistą w Laravel, robiłem na nim mnóstwo rzeczy i znam wiele rozwiązań", a nie mówić: "znam Laravela, pracowałem na nim 3 miesiące, zrobiłem jeden mały projekt" - nie znasz, liznąłeś. Jest takie powiedzenie: "jak coś jest do wszystkiego, to jest do niczego". Ten post edytował Omenomn 10.01.2017, 09:34:46 |
|
|
|
Post
#32
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Pracuję w Kohana 3.2/3.3 od 2 lat. A nie starszej wersji na linii 2.x. W standardzie pobierając to z githuba Kohana 3.3 ma tylko to co jest potrzebne do realizacji w miarę prostych aplikacji, resztę trzeba albo pobrać z innych repo na githubie (a są ciekawe moduły), albo po prostu napisać samemu. Wymagana jest tu jednak gruntowna znajomość tego jak działa ten FW. Bardzo przyjemnie się z tym frameworkiem pracuje. Na pewno nie tylko ja mam taką przyjemność. Jest jeszcze na pewno jakaś wąska grupa programistów PHP która się tym zajmuje.
Ale do czego zmierzam. Dobry kod? Rzecz w tym że KO3 ma dość specyficzne założenia, między innymi CFS, inny styl nazewnictwa (oparty o underline a nie camelCase), jest inaczej niż w Laravelu czy tam Symfony. Jest to dość prosty, lekki i szybki FW. Ale wystarczy przejrzeć inne oprócz Symfony i Laravela, np. Yii, FuelPHP i jeszcze parę innych. I co każdy inny to i inna filozofia i przyjęte założenia w architekturze. Jakim to trzeba być ekspertem żeby (i tu bardzo istotna sprawa) we właściwy i praktyczny sposób stosować te różne wzorce typu dekorator czy tam inne? A pytam o to dlatego, że po roku jak się spojrzy na to co się pisało wcześniej (i tu nie ważne na jakim FW czy też bez niego) to można mieć wrażenie, że wcześniejszy kod można było napisać inaczej. I najprawdopodobniej lepiej albo bardziej praktycznie, bo człowiek się uczy. Ten post edytował daro0 10.01.2017, 11:45:22 |
|
|
|
Post
#33
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Dokładnie, a jakim trzeba być ekspertem, żeby traktować framework jako młotek, że mogę się z jednego przesiąść na drugi i zrobić w nim miazgę.
Trzeba by na każdym jednym z tych młotków pracować po minimum dwa lata i mieć je ogarnięte do maksimum możliwości. |
|
|
|
Post
#34
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
@Omenomn
To co mówisz, składa się na to, co już wcześniej pisałem (inny wątek): Ja uczę się programować, a Ty uczysz się używać czegoś, co ktoś zaprogramował. |
|
|
|
Post
#35
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Dekorator to dobre rozwiązanie, ale nie wystarczające, więc musiałem je połączyć z innym. No to oznacza, że coś jest nie tak z użyciem jego w tym miejscu, skoro zamiast rozwiązać problem pojawił się nowy wynikający z użycia tego wzorca, a dekorowanie dekoratorów, można ale to raczej mija się z celem. Cytat Ja uczę się programować, a Ty uczysz się używać czegoś, co ktoś zaprogramował. I to jest dobre podsumowanie. Bo tu wcale nie chodzi o to czy się przesiadasz z jednego na drugi, napisałem są lepsze i gorsze narzędzia(frameworki). Po jakimś czasie stawianie projektu opanujesz do perfekcji, ale fw za Ciebie dobrego, czystego kodu nie napisze. Jasne masz masę helperów, które dostarcza w pudełku, ale one są uniwersalne, a nie stworzone dla Twoich potrzeb. Skupiając się tylko wokoło nich, produkt który powstanie będzie dostosowany do narzędzia które użyłeś i automatycznie przestanie być uniwersalny. Używasz Laravela, wiec jeśli znasz trochę jego historii tam zdarzały się BC Breaki co wersje, wiec automatycznie w krótkim czasie rośnie w projekcie dług technologiczny, bo nie wielu stać na to, żeby co nowe wydanie zmieniać projekt i dostosowywać pod nowsze jego wersje. Dlatego u nas na forum znajdziesz osoby pracujące np w Zend 1 chociaż mamy już 3, podobnie jest z innymi tego typu narzędziami. |
|
|
|
Post
#36
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Nie potrafię zrozumieć po co tyle zachodu. No ale spoko, to Twoje podejście. Ale np. KO3 daje coś takiego: https://kohanaframework.org/3.2/guide/api/Upload no i jeszcze do obrazków (i np. zmiany rozmiaru) https://kohanaframework.org/3.2/guide/api/Image W tym sensie framework ma swoje helpery do tych operacji. Laravel i inne pewnie też. Bardzo chciałbym wiedzieć jak tego typu rozwiązania (i wzorce jakich użyjesz) przekładają się na praktykę i czy nie będzie problemów z kodami. |
|
|
|
Post
#37
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Chodzi o to, że kod ma rozwiązywać między innymi takie problemy:
- upload jakiegokolwiek pliku - upload obrazka - upload minaturki - upload obrazka z minaturką - upload wideo - upload wideo z miniaturką - upload wideo z trzema miniaturkami - plus mogą wystąpić dodatkowe rodzaje plików lub inne konfiguracje Teraz: - do operacji na plikach mam bibliotekę - do operacji na obrazach mam bibliotekę - i do operacji na filmach mam bibliotekę Wszystkie wykorzystuję w obu rozwiązanich. Zwyczajne podejście to: - Robię kontroler do uploadu plików z metodami np.: uploadVideo, uploadVideoWithThumbnail, uploadImage, uploadImageWithThumbnail i to jest okej, ale: - muszę pobierać za każdym razem atrybuty pliku: 'name' => $file->getClientOriginalName(), 'extension' => $file->getClientOriginalExtension(), 'path' => $file->getRealPath(), - muszę za każdym razem ustawiać kontent: $content = GrImage::make($path); lub $content = \File::get($file); w zależności od typu pliku - muszę kodować: $content->encode($extension); lub nie, jeżeli to video - i wreszcie wrzucić plik: if ($disk->exists($name)) $disk->delete($name); $disk->put($name, $content); Opisałem najprostszą konfigurację. Standardowym podejściem mogę wszystkie metody przechowywać w kontrolerze i w zależności od potrzeb dopisywać następne (co już jest złym podejściem, bo kod powinno się nadbudowywać, a nie zmieniać już napisany). - function putFile() - function getProperties() - function resizeToThumbnail() - function makeThumbnail() - function makeVideo() - function getThumbnailFromVideo() itd. itd... Przez to mam milion metod w kontrolerze i robi się mega bałagan. Natomiast podejście dekoracyjne wygląda tak: - zwykły obraz: $image = new Property( new ContentImage( new Image( new Encoder( new File)))); $image->make($request->file); - miniaturka: $thumbnail = new Property( new ContentImage( new Thumbnail( new Encoder( new File)))); $image->make($request->file); - video: $video = new Property( new Content( new Video( new File))); $video->make($request->file); - video z miniaturką $video = new Property( new ThumbnailFromVideo( new Content( new Video( new File)))); $video->make($request->file); - video z trzema miniaturką $video = new Property( new ThumbnailFromVideo( new GetThumbnail( new ThumbnailFromVideo( new GetThumbnail( new ThumbnailFromVideo( new GetThumbnail( new Content( new Video( new File)))); lub $video = new ThreeThumbnailsFromVideo( new Content( new Video( new File)))); $video->make($request->file); Mogę to nadbudowywać jak mi się żywnie podoba. Dodatkowo wszystkie te klasy są obserwatorami obiektu przechowującego konfigurację pliku, więc jeśli będę chciał dodać obiekt zmieniający nazwę Renamer $video = new ThreeThumbnailsFromVideo( new Content( new Video( new Renamer( new File))))); $video->make($request->file); Wtedy wszystkie obiekty dostają o tym informację (Obserwator). Ostatecznie dekorator wywołuję przez klienta, więc stworzenie miniaturki będzie wyglądało tak: use Acme\MakerClients\Thumbnail; $thumbnail = new Thumbnail; $thumbnail->make($request->file); i tak z każdą zawartością. Chyba macie zbyt sztywne podejście do wzorców, czemu mam stosować jeden, skoro mogę połączyć dwa, to jest o wiele bardziej konstruktywne i ciekawe niż trzymanie się konkretnego wzorca jak sztywnych zasad 10-ciu przykazań. Ten post edytował Omenomn 10.01.2017, 19:11:09 |
|
|
|
Post
#38
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
Skoro chcesz obsługiwać upload po typie pliku to Factory będzie lepszym rozwiązaniem lub Strategia.
|
|
|
|
Post
#39
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Też mi się wydaje że coś na wzór tego mogło by był dobrym rozwiązaniem. Np. tak:
W tym założeniu (tylko że ja biorę pod uwagę KO3) musiałbym mieć w katalogu application/classes podkatalog Uploader a w nim odpowiednio: Image.php Video.php Music.php i wszystkie te klasy musiałyby rozszerzać:
która to klasa musiałaby być w katalogu classes Odrębna sprawa to identyfikacja co i czym jest bo po rozszerzeniu pliku to dość prosta sprawa. |
|
|
|
Post
#40
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Po typie pliku jest tylko jeden upload, który ma zdecydować po rozszerzeniu, czy uploadować wideo z thumbnailem, czy obraz z thumbnailem dla sliderów, ale rzeczywiście, może do decyzji o tym użyję innego wzorca.
Jednak to co pokazałeś daro0 w jaki sposób wykorzystuje kod klas poniższych, jak w dekoratorze? Czyli, że upload obrazu wykorzystuje ten sam kod do uploadu pliku co wideo: if ($disk->exists($name)) $disk->delete($name); $disk->put($name, $content); i jak w jednym miejscu ogarniesz metodę do pobrania atrybutów pliku, żeby zrobić z nim później co się chce? Jak to rozwiążesz strategią lub factory? |
|
|
|
Post
#41
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
Przede wszystkim obsługa zapisu/usuwania pliku powinna być oddelegowana do oddzielnej klasy np. StorageHandler(new LocalStorage());
I tam sobie dajesz np. $storage->store((File)$file); Czyli defacto masz 2 fabryki: 1 do obsługi pliku samego w sobie a 2 do zapisu/odczytu/usuwania. Wynikiem 1-szej powinien byc obiekt z którego pobierzesz sobie jakieś tam atrybuty. Wew. niego możesz mieć obiekt np. miniaturki itd itd. |
|
|
|
Post
#42
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Zakładam że są trzy klasy: Uploader_Image, Uploader_Video oraz Uploader_Music, trzy osobne pliki PHP. Zakładam że rozszerzenie będzie w jakiś sposób ustalane na podstawie tego co jest w $_FILES['attachment']['name'] i jest wyciągane i na podstawie np tego:
To tylko jeden z możliwych sposobów. |
|
|
|
Post
#43
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
ale Wy się cały czas rozszerzeniem zajmujecie, a to jest tylko jeden z problemów i to nie aż tak istotny, nie kumacie, czy nie wiem co...
Opisałem to wcześniej. Jak daro0 chciałbyś utworzyć tym rozwiązaniem sam obraz, albo obraz z miniaturką? albo samo wideo, albo wideo z miniaturką, albo wideo z trzema miniaturkami? Czy dekoracja, sama w sobie nie nasuwa się na myśl? Masz plik i go dekorujesz, "tu mu zmienię rozmiar, tu mu zmienię rozszerzenie, tu mu zmienię nazwę, tu jeszcze coś innego mu zmienię" (IMG:style_emoticons/default/biggrin.gif) i tak sobie zmieniam jak mi się podoba. Tak w ogóle jak czytam te tutoriale z nazwami klas, metod i zmiennych po polsku, to od razu wiem, że taki tutorial to śmieć. Jaki dobry programista używa polskich nazw w programowaniu. Ten post edytował Omenomn 10.01.2017, 21:48:42 |
|
|
|
Post
#44
|
|
|
Grupa: Zarejestrowani Postów: 251 Pomógł: 23 Dołączył: 23.04.2013 Ostrzeżenie: (0%)
|
Sądzę, że każdy ma podobne rozterki do Twoich. (IMG:style_emoticons/default/wink.gif)
Pisząc prywatne projekty zawsze biorę pod uwagę "czystość kodu" do "czasu pracy". Każdy ma jakieś wyobrażenie o tym jaki powinien być kod, a także każdy ma swoje nawyki. Wydaje mi się, że większość z nas ma lepsze wyobrażenie o swojej pracy, niż ona w rzeczywistości wygląda - a widać to najlepiej przy prywatnych projektach. ; ) Uczymy się wzorców, mówimy sobie, że testy i czystość kodu (znana książka "Czysty Kod") są ważne, ale gdy zaczynamy pracę nad jakimś projektem, to nie zawsze trzymamy się idealnie swoich teorii. Ja osobiście ciągle podejmuję decyzje typu: "zostawić tutaj drobny bałaganik do posprzątania na później czy posprzątać już teraz?". Najważniejsze to najpierw nauczyć się pokory - pamiętam doskonale czas, kiedy uczyłem się bardzo dużo nt. programowania, wzorców, czystego kodu, testowania. Sam siebie uważałem za wybitnego programistę. Jednak podczas pewnego projektu śpieszyłem się z dostarczeniem pewnego oprogramowania. Po dwóch miesiącach pisania kodu nagle zdałem sobie sprawę, że złamałem prawie wszystkie zasady, w jakie głęboko wierzyłem - dostrzegłem wtedy jaką byłem żałosną istotą... ; ) Pomyślałem sobie - Damianie, Ty tępy ch#&$^, uważasz się za tak dobrego programatora, a tutaj tworzysz takie g$%#$, że smród rozchodzi się po całości. Pamiętam także jedną aplikację, dość dużą. Pisałem ją przez jakiś rok (prywatny projekt). Po długiej przerwie bylem zmuszony do pewnych modyfikacji, zajrzałem więc do starego kodu i... ni cholery nie mogłem się połapać w jednej części kodu. Po prostu stworzyłem tak cholernie skomplikowany kawałek kodu, że musiałem przez prawie dwie godziny go analizować, aby połapać się o co w nim chodziło. Jaka jest moja rada? Nie ma kodu doskonałego. Goni nasz wszystkich czas. Nawet jeśli masz dobre zamiary, to często robisz małe grzeszki. Małe grzeszki nie są złe, o ile się nie rozrastają. Ze swojej strony powiem tylko tyle, że wszystko zależy od nastroju i nastawienia. Pisałem prywatne projekty, w których naprawdę działałem według swoich zasad, tj. pełne skupienie na "czystości" i "otestowaniu". Wielbię Wujka Boba, więc tworzyłem soft otestowany w 90-kilku procentach. Siedziałem nad nim długo, starałem się go ciągle refaktoryzować, nawet gdy niektóre rozwiązania zabierały dużo czasu. Widziałem tego efekty. Widziałem, że warto mieć testy. Ale... nawet teraz po latach doświadczenia potrafię się śpieszyć i tworzyć oprogramowanie "na szybko", bez testów, z "małymi grzeszkami". Ważne, aby mieć jakieś standardy. Gdy łamię zasady, wtedy coś za uchem mówi mi "grzeszysz". Popełniam grzeszki. Ale mam jednak pewne "standardy grzeszenia". Mogę pisać kod, który nie jest otestowany. Mogę czasem wprowadzić jakąś mała zawiłość. Ale jesli widzę, że coś staje się zbyt skomplikowane, albo zbyt nieczytelne, wtedy włącza się alarm i wprowadzam porawki. W końcu większość z nas wie jakie problemy wiążą się z nieczystym kodem. Doświadczyliśmy tego. Wiemy co robić, aby nie kopać pod sobą dołków. Czasem grzeszymy. To normalne. Ważne, aby mieć jakieś normy. |
|
|
|
Post
#45
|
|
|
Grupa: Zarejestrowani Postów: 1 045 Pomógł: 141 Dołączył: 19.09.2006 Skąd: B-tów Ostrzeżenie: (0%)
|
Tak w ogóle jak czytam te tutoriale z nazwami klas, metod i zmiennych po polsku, to od razu wiem, że taki tutorial to śmieć. Jaki dobry programista używa polskich nazw w programowaniu. Zajrzy do baz danych takich programów jak optima lub xl od comarch-a, subiekt od insert-tu czy wf-mag od wapro. W ich bazach nie znajdziesz słowa po angielsku, a nie ukrywajmy są to jedne z większych firm w Polsce. Idąc Twoim tokiem rozumowania ich produkty które zarabiają pewnie niezłe melony to śmieci.... Ale to temat na nieco inną rozmowę (IMG:style_emoticons/default/wink.gif) |
|
|
|
Post
#46
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Chcesz mi wmówić, że stosowanie polskiego nazewnictwa jest okej?
Zarabianie oprogramowania, nie jest równe z tym, że jest dobrze napisane. Strony na wordpressie też zarabiają (IMG:style_emoticons/default/biggrin.gif) Ten post edytował Omenomn 10.01.2017, 22:49:31 |
|
|
|
Post
#47
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Jak daro0 chciałbyś utworzyć tym rozwiązaniem sam obraz, albo obraz z miniaturką? albo samo wideo, albo wideo z miniaturką, albo wideo z trzema miniaturkami? Omenomn A Twoim gdzie niby stwierdzę, że mam wybrać te a nie inne rozwiązanie. Cytat Czy dekoracja, sama w sobie nie nasuwa się na myśl? Nie, za to strategia już tak (IMG:style_emoticons/default/wink.gif) Przyjrzyjmy się definicji: Dekorator, pozwala na dynamicznie dodawanie nowych funkcjonalności do istniejących klas podczas działania programu. Strategia, tworzy wspólny interfejs z dozwolonymi operacjami oraz listę klas implementujących dany interfejs dostarczających konkretne algorytmy. Factory, dostarcza interfejs do tworzenia obiektów nieokreślonych typów, pozwala podklasom zdecydować, jakiego typu będzie obiekt I powiedz mi gdzie tu pasuje Twój kod. Co z tego że udekorujesz sobie jakaś klasę jak nie stwierdzisz, że w tym konkretnym miejscu ona ma być tak udekorowana. Pomijając fakt, że zamieniłeś znaczenie modelu w Twoim rozwiązaniu, bo teraz dekorujesz obiekt własnościowi a to miał być podobno upload. |
|
|
|
Post
#48
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
upload, a przed uploadem odpowiednio się plik, a teraz uwaga ------ dekoruje.
Cytat Dekorator, pozwala na dynamicznie dodawanie nowych funkcjonalności do istniejących klas podczas działania programu. Własności też, nie tylko funkcjonalności. Cytat I powiedz mi gdzie tu pasuje Twój kod. Co z tego że udekorujesz sobie jakaś klasę jak nie stwierdzisz, że w tym konkretnym miejscu ona ma być tak udekorowana. Pomijając fakt, że zamieniłeś znaczenie modelu w Twoim rozwiązaniu, bo teraz dekorujesz obiekt własnościowi a to miał być podobno upload. Stwierdzę. Kontroler ma metodę przypisaną do routingu, więc jak wyślę coś postem na strona.com/image, to mam w kontrolerze metodę image(), w której wywołuję $image = new PropertyGeter( new ContentImageGeter( new ImageNoResizer( new Encoder( new FilePuter)))); $image->make($request->file); i mam upload obrazu, jak chcę obraz z jego miniaturką to strona.com/image-with-thumbnail, metoda imageWithThumbnail() $image = new PropertyGeter( new ContentImageGeter( new ThumbnailResizer( new Encoder( new FilePuter)))); $image->make($request->file); itd. Nie potrzebuję wzorca decydującego o tym jaki plik ma zostać stworzony, bo doskonale wiadomo jaki. http://stackoverflow.com/questions/1234554...e-re-sizing-etc Ten post edytował Omenomn 10.01.2017, 23:15:07 |
|
|
|
Post
#49
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Własności też, nie tylko funkcjonalności. To nie moja definicja, ok własności tez mogą być. Ale nie to jest ważne a słowo nowe własności/funkcjonalności. Spójrz na swój kod i co można tam zauważyć $image = new PropertyGeter( new ContentImageGeter( new ImageNoResizer( new Encoder( new FilePuter)))); $image = new PropertyGeter( new ContentImageGeter( new ThumbnailResizer( new Encoder( new FilePuter)))); 95% tego kodu to tak naprawdę spójny interfejs, który mógłby tworzyć jedna całość, a reszta to już tylko odpowiedni wybór ścieżki dla algorytmu. Cytat Stwierdzę. Kontroler ma metodę przypisaną do routingu, więc jak wyślę coś postem na strona.com/image No czyli masz jakaś strategie o niespójnym interfejsie do obsługi i daj to komuś żeby zrozumiał taki kod, a potem użył z nowym schematem bo klient wymyślił sobie że teraz nie 3 miniaturki a 4. Załóżmy, że piszesz testy, jak taki kod przetestować skoro nie wiesz co tak naprawdę uzyskasz, bo w zależności od tego jak go wywołasz otrzymasz inny wynik, i co jeśli o czymś po drodze zapomnisz, bo dodałes nowe funkcjonalności i zamiast tych 5 dekoratorów masz już ich 20/30/100. Ten post edytował com 10.01.2017, 23:27:17 |
|
|
|
Post
#50
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
No to wtedy robi się nakładkę.
Cytat Spójrz na swój kod i co można tam zauważyć
Co można zauważyć? że za każdym razem jest pobierana właśność do pliku i ustalany content, kodowanie i zapis? Sprawdź sobie jak wygląda upload video z miniaturką:
lub samo video. czy inny plik:
i jakie teraz własności kodu wywnioskowałeś? Cytat No czyli masz jakaś strategie o niespójnym interfejsie do obsługi i daj to komuś żeby zrozumiał taki kod, a potem użył z nowym schematem bo klient wymyślił sobie że teraz nie 3 miniaturki a 4. Każdy framework tak ma, nie wiesz? Ten post edytował Omenomn 10.01.2017, 23:40:04 |
|
|
|
Post
#51
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
No dokładnie te same dla tej grupy wideo, tak samo będzie dla audio i czego sobie tam jeszcze nie wymyślisz.
Każda grupa to jakiś schemat, który dodatkowo rozbudowujesz i zależnie od tego jak skomponujesz te obiekty taki uzyskasz context, ale dla każdej operacji będzie on inny choć operujesz dalej na tym samym obiekcie, wiec oczekujesz dostać ten obiekt, a nie cokolwiek. Cytat Każdy framework tak ma, nie wiesz? Wskaż mi gdzie framework ma coś nie udokumentowane i nie wiesz co uzyskasz jak wykonasz dany fragment jego kodu. To trochę tak jakbyś z kota chciał zrobić mysz To jak się uparłeś już na te twoje "dekoratory" to zrób chociaż Fasade, żeby to można było produktywnie wykorzystać. Tylko to jest trochę bez sensu. Bo ile teraz ktoś kto chce dodać głupi obrazek musi pamiętać, żeby taki plik dodać. A wzorce maja dawać te możliwość, że jedno rozwiązanie możesz wprost wyjąc z tego projektu i dodać do innego i tam też będzie działać i teraz zamiast kod się sam dokumentować, piszesz how to use. Dekorator jest rozwiązaniem które można tu zastosować ale tak jak już zostało napisane: Cytat Dekoratorem może być tutaj tylko Thumbnail bo on faktycznie coś tam robi na źródłowych danych. czy jak na tym stacku który podrzucałeś:
Cytat Jak we wzorcu dekorator przekazywać pomiędzy obiektami atrybuty elementu dekorowanego, tak, żeby każda klasa miała do nich dostęp i mogła je modyfikować i, żeby każdy obiekt widział te zmiany. Tak:http://blogophp.com/2009/08/16/dekorator/#more-40 Pierwsze co powinno To Cie właśnie zastanowić, że coś jest tutaj nie tak, skoro tak nie jest. Jak już używamy wzorców to trzeba ich używać dobrze, bo inaczej zamiast kod rozjaśnić zaciemniamy go. Podsumowując, właściwości nie powinny wędrować miedzy dekoratorami, bo wtedy już to nie jest dekorator! Dekorujesz konkrety obiekt bazę która rozszerzasz, a nie budujesz nad obiektem bazy nowego obiektu do rozszerzeń. Każdy dekorator to niezależny byt, który możesz wywołać bezpośrednio na obiekcie bazowym zawsze i nie potrzebujesz do tego więcej dekoratorów po drodze. To:
i to:
Ma dać ten sam efekt, daje, zapewne nie bo ThumbnailFromVideoCuter() zależy pewnie od obiektu PropertyGeter(), skoro potrzebny był Ci obserwator. Ten post edytował com 11.01.2017, 00:52:22 |
|
|
|
Post
#52
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Cytat Wskaż mi gdzie framework ma coś nie udokumentowane i nie wiesz co uzyskasz jak wykonasz dany fragment jego kodu. To trochę tak jakbyś z kota chciał zrobić mysz Mówię o routingu. Dziwnie Cię zdziwiło, że są metody przypisane do konkretnej akcji z urla. Cytat Podsumowując, właściwości nie powinny wędrować miedzy dekoratorami, bo wtedy już to nie jest dekorator! Dekorujesz konkrety obiekt bazę która rozszerzasz, a nie budujesz nad obiektem bazy nowego obiektu do rozszerzeń. Każdy dekorator to niezależny byt, który możesz wywołać bezpośrednio na obiekcie bazowym zawsze i nie potrzebujesz do tego więcej dekoratorów po drodze. Miedzy dokoratorami będę przekazywał obiekt, w którym będzie się znajdował kontent pliku plus inne atrybuty, które można modyfikować, a nie jak do tej pory sam kontent. Dlatego musiałem rozwiązać problem przekazywania właściwości, ale z obiektem będzie prościej o wiele. Cytat To:
i to:
Ma dać ten sam efekt, daje, zapewne nie bo ThumbnailFromVideoCuter() zależy pewnie od obiektu PropertyGeter(), skoro potrzebny był Ci obserwator. Nieprawda, znajdź mi informację, że w dekoratorze kolejność dekoratorów ma nie mieć znaczenia. Choćby zawsze musi istnieć końcowy dekorator, który nie przyjmuje wartości do konstrukora, więc jeżeli musi istnieć końcowy, to może istnieć początkowy i może istnieć ustalona kolejność. |
|
|
|
Post
#53
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Prawda jest taka, że gdybym miał się tak zastanawiać nad tym wszystkim to bym nigdy nie skończył w terminie żadnego projektu a wymagania są określone przez klienta. Owszem czasem trzeba coś dodać, coś nie było przewidziane, jednak na ogół nie jest to problemem. Tak na szybko (pierwsze co mi przychodzi na myśl). Zakładam że jest formularz typu Multipart/Formdata w widoku a w nim daje się jakiś opis w pole tekstowe, jest pole do wybierania obrazka do uploadu oraz opcja checkbox, czy ma być miniaturka czy też nie a rozmiary są określone w konfiguracji frameworka.
application/classes/Request.php
i metoda kontrolera
To jest tylko jedno z możliwych podejść. Tutaj to czy jest miniaturka czy nie to jest określone na podstawie tego co zwraca $_POST a ten helper musiałby na podstawie tego wykonywać pewne operacje. Zakładam użycie helperów Image oraz Upload z tego frameworka. Nie wiem jak by to wyglądało w Laravelu a już tym bardziej gdyby pisać całkowicie od zera. Ten post edytował daro0 11.01.2017, 09:51:16 |
|
|
|
Post
#54
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Jak się poświęci więcej czasu przy jednym projekcie na dobre rozwiązanie problemu, to później tego rozwiązania można używać w kolejnych, i czas wykonania skraca się o wiele.
Piszą o tym w książkach o wzorcach i dobrych praktykach. Problem jest rozwiązany i działa meeega!! Teraz mam bibliotekę rozszerzalną na miliony sposobów, gotową do użycia w innych projektach. |
|
|
|
Post
#55
|
|
|
Grupa: Zarejestrowani Postów: 623 Pomógł: 144 Dołączył: 22.12.2010 Ostrzeżenie: (0%)
|
|
|
|
|
Post
#56
|
|
|
Grupa: Moderatorzy Postów: 36 561 Pomógł: 6315 Dołączył: 27.12.2004 |
Cytat Tylko pytanie czy inni też będą wiedzieli jak tę bibliotekę szybko i łatwo użyć? Soryy, ale nie bede sobie "nieulatwial" pracy tylko dlatego ze ktos moze kiedys nie wiedziec jak tego uzyc... Ja tez mam wlasne liby w Symfony ktore generalizuje mi rozne rzeczy, np Grid, edycja, usuwanie, w sume caly CRUD. Na napisanie tego poswiecilem chwilke czasu ale teraz kazdy kolejny CRUD to 15 minut robotyi wiem ze wszystko bedzie dzialac tak samo.Wracajac do twojego pytania: Po pierwsze, skoro klasa byla uzywana w projekcie, to sa przyklady uzycia Po drugie, zazwyczaj jak potrzeba pisze sie komentarz. |
|
|
|
Post
#57
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Zgadzam się z nospor
|
|
|
|
Post
#58
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Mówię o routingu. Dziwnie Cię zdziwiło, że są metody przypisane do konkretnej akcji z urla. Nie napisałem że coś w tym dziwnego, napisałem, że masz tu strategie o której ja i inni mówiliśmy. Cytat Nieprawda, znajdź mi informację, że w dekoratorze kolejność dekoratorów ma nie mieć znaczenia. Choćby zawsze musi istnieć końcowy dekorator, który nie przyjmuje wartości do konstrukora, więc jeżeli musi istnieć końcowy, to może istnieć początkowy i może istnieć ustalona kolejność. Wgl nie zrozumiałeś dekoratorów. Jedyne co musi istnieć to klasa która rozszerzasz, ona ma jakaś funkcjonalność w Twoim przypadku bazą jest Upload. I kiedy podczas tego uploadu zależy Ci żeby powstała miniaturka, wiec dodajesz do istniejącego obiektu Uploadu zrób mi miniaturkę. Dlatego tworzysz dekorator, którego jedynym zadaniem jest zmienić obiekt bazowy tak żeby zamiast pełnego obrazu zwrócona została miniaturka w jego miejscu. Dla innego route chcesz miniaturkę obrócona o 180 stopni. Wiec bierzesz klase Upload bierzesz dekorator Thumbnail i dekorator Rotate i masz miniaturkę i obrócony. Ale nie ma znaczenia czy najpierw obrócisz potem zmniejszysz czy na odwrót i tak i tak efekt zawsze jest taki sam i tak powinno być u Ciebie, a tak nie jest bo u Ciebie każda klasa zależy od innej. W przypadku prawdziwego dekoratora nadawane ograniczenia/zmiany na obiekcie są od siebie nie zależne, wiec mogę mięć: miniaturkę; miniaturkę i obrócony == obrócony i miniaturka; obrócony, a wszystko to bez jakiejkolwiek zmiany w kodzie. Twoje początkowe założenie było blednę, czyli: Cytat Choćby zawsze musi istnieć końcowy dekorator Nie ma czegoś takiego jak początkowy czy końcowy dekorator, jest obiekt który dekorujesz i jeśli dekoratory maja ten sam interface co ten obiekt, to można je ze sobą składać tak jak było opisane w przykładach, ale tylko i wyłącznie wtedy. Cytat Soryy, ale nie bede sobie "nieulatwial" pracy tylko dlatego ze ktos moze kiedys nie wiedziec jak tego uzyc... Tu wcale nie chodzi o nie ułatwianie pracy, bo po to zaproponowane zostało użycie wzorców, żeby te rozwiązanie było jak najbardziej elastyczne i można było wykorzystać je w wielu projektach, ale wzorce zostały zdefiniowane w taki sposób, żeby każdy kto sporzy na kod, znając je wie jaki będzie efekt. A kiedy kolega Omenomn po roku czy dwóch latach wróci do tego kodu coś zmienić, najpierw znów będzie musiał wdrożyć sam siebie jak to działa i czemu tak to zrobiłem wtedy a nie inaczej. Przeczytaj jeszcze raz uważnie co tam zostało napisane http://blogophp.com/2009/08/16/dekorator/#more-40 Najistotniejsze fragmenty Cytat // obiekty tej klasy beda dekorowane class SimpleText extends Information Cytat Proszę zwrócić uwagę na fakt, iż gdy obiekt dekorowany jest tego samego typu co dekoratory jesteśmy w stanie ?dekorować? również dekoratory obiekt dekorowany !== dekorator i nie możesz go nazwać dekoratorem końcowym. Pomijając już sam fakt, że tak jak tam było: new FirstLetter(new TextLength(new SimpleText())); Dekoratory idą od środka w górę, a u Ciebie odnoszę wrażenie, że idziesz od początku w dół, przynajmniej tak wynikało z pierwszego opisu. Trochę wracając jeszcze do tematu frameworka i jego roli, o czym mówiliśmy wcześniej to przykład od olx: (IMG:http://i63.tinypic.com/bjm9.png) Ten post edytował com 11.01.2017, 19:27:12 |
|
|
|
Post
#59
|
|
|
Grupa: Zarejestrowani Postów: 26 Pomógł: 10 Dołączył: 17.03.2012 Ostrzeżenie: (0%)
|
Nieprawda, znajdź mi informację, że w dekoratorze kolejność dekoratorów ma nie mieć znaczenia. Choćby zawsze musi istnieć końcowy dekorator, który nie przyjmuje wartości do konstrukora, więc jeżeli musi istnieć końcowy, to może istnieć początkowy i może istnieć ustalona kolejność. Principle of least astonishment jak to się w kulturze OOP nazywa. Gdy kolejność ma znaczenie to wprowadzasz składnię a to się liczy conajmniej jako "zaskoczenie". Precyzując, Dekorator implementuje ten sam interfejs, który implementuje obiekt który jest dekorowany. Żeby dekorator mógł korzystać z pól dodanych przez inny dekorator, musisz wprowadzić drugie drzewo dekoratorów bazujące na poszerzonym interface albo ich produkcie. Ten post edytował solificati 11.01.2017, 15:34:27 |
|
|
|
Post
#60
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Jeszcze rok albo dwa lata temu przy wcześniejszych projektach to też myślałem że to co wtedy pisałem jest super. Jakże się myliłem, bo teraz jak na to popatrzę to aż szlak trafia bo można było to napisać inaczej. Ale dalej. Weźmy np. nie uploader ale StaticServer
I tak: http://localhost/image/serve - wyświetla oryginalny obrazek JPG który wczyta http://localhost/image/serve?size=50 - wyświetla obrazek w rozmiarach 50% oryginału http://localhost/image/serve?size=50&sharp=100 - to samo ale wyostrzone http://localhost/image/serve?quality=10 - jakość JPG 10% http://localhost/image/serve?rotate=90 - obraza o 90 stopni w prawo Domyślnie metoda __toString() wywołuje na render() w tym module. I teraz jest pytanie, co w takim przypadku daje zastosowanie dekoratora (bo też można by to zrobić) vs. to podejście jakie jest tu? |
|
|
|
Post
#61
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
daro0 seriooo?(IMG:style_emoticons/default/questionmark.gif) Ten kod jest naprawdę kiepski...
to podejście jest nawet gorsze od tego, które chciałem poprawić. com przykładowy dekorator
Widzisz, że Decorator3 nie przyjmuje obiektu? Chcesz mi tłumaczyć coś, czego sam nie kumasz i jeszcze wmawiasz mi, że tego nie rozumiem. Ten post edytował Omenomn 11.01.2017, 22:17:29 |
|
|
|
Post
#62
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
@Omenomn weź w końcu przeczytaj co to jest Decorator i przestań się upierać przy czymś o czym nie masz pojęcia bo aż szkoda.
|
|
|
|
Post
#63
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Szlag mnie trafi:
http://blogophp.com/2009/08/16/dekorator/#more-40 Cytat Jeśli chcemy zezwolić na wyświetlanie na wyjściu wiadomości, których długość przekracza pięć znaków wystarczy zapis:
Warunki mogą być łatwo dołączane jak zaprezentowano poniżej:
W ten prosty sposób możemy dowolnie nakładać ograniczenia na parametr $message. Proszę zwrócić uwagę na fakt, iż gdy obiekt dekorowany jest tego samego typu co dekoratory jesteśmy w stanie ?dekorować? również dekoratory ? tak właśnie dzieje się w powyższym przykładzie. Zachęcam do korzystania z tego wzorca. Cytat z linku, widzisz, żeby SimpleText przyjmowała obiekt? Więc chyba musi być ostatnia, no nie?(IMG:style_emoticons/default/questionmark.gif) (IMG:style_emoticons/default/questionmark.gif) (IMG:style_emoticons/default/questionmark.gif) ? Proste jak konstrukcja cepa. Najwyraźniej nie dla wszystkich. Ten post edytował Omenomn 11.01.2017, 22:58:25 |
|
|
|
Post
#64
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
SimpleText nie jest ostatnim a pierwszym. Na dodatek nie jest dekoratorem a Obiektem bazowym który jest DEKOROWANY a NIE jest DEKORATOREM.
|
|
|
|
Post
#65
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Omenomn Specjalnie Ci już podkreśliłem fragmenty z tego bloga, ale zamiast przeczytać ze zrozumieniem uparłeś się na swoje rozwiązanie. Przeczytaj jeszcze raz co ja napisałem i co napisał Pyton_000 i można zakończyć te dyskusję.
Ostatecznie dekoratory bez klasy bazowej nie istnieją bo nie maja co dekorować, dlatego zawsze musi być jakaś baza tak jak tam jest to SimpleText, który nie jest dekoratorem, nim są dopiero TextLength oraz FirstLetter. Źle przeczytałeś i potem dobudowałeś sobie do tego teorie, zdarza się (IMG:style_emoticons/default/smile.gif) SimpleText możesz zawsze wywołać wgl bez dekoratorów i spełni swoje podstawowe zadanie, dekoratora nie da się bo nie będzie klasy która dekoruje i tyle.
Tak miał wyglądać Twój kod dla Twojego przykładu (IMG:style_emoticons/default/wink.gif) Ten post edytował com 12.01.2017, 01:15:38 |
|
|
|
Post
#66
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Okej, teraz widzę, że w tych tutorialach oni ostatni dekorator przekazują jako obiekt do dekorowania.
Jednak klasa SimpleText musi implementować interfejs dekoratora, wymagany w konstruktorze dekoratora TextLength, więc jeśli implementuje interfejs dekoratora to też nim jest, według mojego rozumowania. Pierwszy dekorator jaki wywołuje metodę write() to FirstLetter, więc jest pierwszy, a ostatnia wywołana metoda jest z SimpleText.
Co przekazujesz w tym kodzie do zmiennej $object? Nie widzisz tu błędu logicznego? Teorycznie metoda make() może nie przyjmować parametru i wtedy pracujesz na sztywnych danych z ObjectToDecorate(), ale według mnie lepiej jest przekazać do metody make($object), obiekt do obróbki a klasę ObjectToDecorate (w tym przypadku nazwa błędna) potraktować jako ostatni krok obróbki obiektu $object. Takie podejście wydaje mi się o wiele sensowniejsze. Po za tym co to ma do rzeczy, że jest w dekoratorze ustalona kolejność. Może być tak, że któryś z dekoratorów zmieni dane, które otrzymał w taki sposób, że dekorator przed nim nie byłby w stanie ich obsłużyć, jeśli wystąpi po nim. Wymyślanie problemów tam gdzie ich nie ma. Ten post edytował Omenomn 12.01.2017, 08:52:00 |
|
|
|
Post
#67
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Omenomn
Tym razem nie Kohana i nie wiem czy jest to do końca poprawnie ale podczas pisania tego kodu myślałem że zwariuję(IMG:style_emoticons/default/exclamation.gif) ! Dosłownie.
Też chodzi o ładowanie JPEG oraz przy użyciu jak (poprawnie?(IMG:style_emoticons/default/questionmark.gif) ) myślę dekorowania bazowego Image tak żeby uzyskać efekty w odcieniach szarości albo nagatywu obrazu. W takim razie odpowiedz mi na pytanie: po co tyle zabawy?(IMG:style_emoticons/default/questionmark.gif) ? Mam jeszcze dekorować ten udekorowany obiekt w ten sposób:
A co z dodatkowymi opcjami? Albo jeszcze takie coś:
vs. to:
Co też moim zdaniem można zrobić bardzo prosto w tylko jednej klasie operując na resource i tych wbudowanych funkcjach z modułu GD. |
|
|
|
Post
#68
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
single responsibility principle - słyszał?
|
|
|
|
Post
#69
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Cytat
Co też moim zdaniem można zrobić bardzo prosto w tylko jednej klasie operując na resource i tych wbudowanych funkcjach z modułu GD. Wydaje mi się, że o wiele gorzej z dodawaniem kolejnych funkcji przy takim rozwiązaniu, bo w końcu klasa może urosnąć do gigantycznych rozmiarów z ogromną ilością metod, a właśnie ten problem chciałem wyeliminować. Trzeba pamiętać o tym, że to ma obsługiwać różne pliki, nie tylko obrazy, ale też wideo. Czyli właśnie zasada jednej odpowiedzialności jest tu wykluczona, bo jeśli jeszcze można by ją odnieść do obrazu, to nie odniesie się tego do uploadu filmu z wygenerowaniem trzech miniaturek. Po za tym istnieje taka klasa do obróbki obrazów jaką przedstawiasz daro0: http://image.intervention.io/ i Ja ją wykorzystuję właśnie w moim dekoratorze. Ten post edytował Omenomn 12.01.2017, 09:53:41 |
|
|
|
Post
#70
|
|
|
Grupa: Zarejestrowani Postów: 160 Pomógł: 27 Dołączył: 22.09.2008 Skąd: Tarnów Ostrzeżenie: (0%)
|
@Omenomn
Męczysz się chłopak niemiłosiernie. Przeczytaj i przeanalizuj to, co jest napisane w Czystym Kodzie + SOLID. Sam kiedyś tak kombinowałem jak Ty. Tak jak ktoś już wcześniej napisał - uzbrój się w pokorę, przeczytaj, i zastanów się nad sensem tego, co tam jest napisane. Nie bez powodu jest to best seller. |
|
|
|
Post
#71
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Przeczytam na pewno.
Ps. Nie męczę się, bo już to jest gotowe i dobrze działa. Tak sobie ogólnie pomyślałem teraz, że tak jak backend tworzy się pod frontend, tak bebechy bibliotek do obsługi jakichś zadań powinno się tworzyć pod sposób ich wywoływania. Czyli najpierw zastanowić się trzeba jak chce się korzystać z danej biblioteki, jak ją wywoływać, a później dopiero tworzyć jej wnętrze. Ten post edytował Omenomn 12.01.2017, 20:21:24 |
|
|
|
Post
#72
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Dalsza dyskusja nie ma sensu wiec na tym poście zakończę.
Cytat Okej, teraz widzę, że w tych tutorialach oni ostatni dekorator przekazują jako obiekt do dekorowania. No bo taka jest definicja dekoratora. Masz obiekt do dekorowania który istniej zanim wgl ktokolwiek pomyśli o tym żeby stworzyć dekorator i masz dekoratory które dodają nowe funkcjonalności do klasy nie modyfikując jej. Cytat Jednak klasa SimpleText musi implementować interfejs dekoratora Co za bzdury gadasz, to nie klasa która dekorujesz musi implementować interfejs dekoratora, a dekoratory interfejsy klasy która dekorują. Czyli zupełnie na odwrót. Cytat Teorycznie metoda make() może nie przyjmować parametru i wtedy pracujesz na sztywnych danych z ObjectToDecorate(), ale według mnie lepiej jest przekazać do metody make($object), obiekt do obróbki a klasę ObjectToDecorate (w tym przypadku nazwa błędna) potraktować jako ostatni krok obróbki obiektu $object. Pracując na sztywnych danych jaki miałby sens dekorować klasę, skoro bez jej modyfikacji niczego nie jesteś wstanie zmienić. Podstawowym zadaniem które da się tu zrobić jest wykonanie takiego kodu:
Nie potrzebuje mieć ani jednego dekoratora, żeby taki kod wywołać, bo on dostarcza to co daje mi interfejs. To co Ty stworzyłeś nie można nazwać po prostu dekoratorem. Stworzyłeś własna implementacje jako rozwiązanie dla tego problem, bo to co Ty masz nawet obok dekoratora nie stało. Tylko te rozwiązanie ma dwa podstawowe problemy, nie jest testowalne i skalowalne. Wraz z każdym dekoratorem wzrasta złożoność tego rozwiązania i uzależnienie jednego obiektu od drugiego. Ale jedno muszę Ci przyznać wykazałeś się pomysłowością w wymyślaniu "koła" na nowo, bo otrzymałeś coś co w programowaniu istnieje od dawna pod nazwą dziedziczenie, tylko zamiast zrobić to tradycyjnie, stworzyłeś implementacje poprzez składanie obiektów. (IMG:style_emoticons/default/biggrin.gif) |
|
|
|
Post
#73
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
i tak głównie chodzi o warstwowe nakładanie klas new Class(new Class1( new Class2( itd.)))
To, czy Class2 traktujesz jako obiekt dekorowany, czy ostatni dekorator nie ma takiego znaczenia. Cytat Ale jedno muszę Ci przyznać wykazałeś się pomysłowością w wymyślaniu "koła" na nowo, bo otrzymałeś coś co w programowaniu istnieje od dawna pod nazwą dziedziczenie, tylko zamiast zrobić to tradycyjnie, stworzyłeś implementacje poprzez składanie obiektów. To nie jest dziedziczenie tylko przypisanie, co czyni ogromną różnicę. Cytat Tylko te rozwiązanie ma dwa podstawowe problemy, nie jest testowalne i skalowalne. Wraz z każdym dekoratorem wzrasta złożoność tego rozwiązania i uzależnienie jednego obiektu od drugiego. Jest testowalne. Przetestowałem, działa, chociaż jest dość zawiłe w implementacj, jeszcze nad tym popracuję Cytat Cytat Jednak klasa SimpleText musi implementować interfejs dekoratora Co za bzdury gadasz, to nie klasa która dekorujesz musi implementować interfejs dekoratora, a dekoratory interfejsy klasy która dekorują. Czyli zupełnie na odwrót. Chodziło mi o to, że mają ten sam interfejs. Widzę, że wszędzie piszą tak jak Ty tutaj, rzuciłem okiem na ten wzorzec i jakoś mi umknęło to, że ostatni obiekt ma być traktowany jako obiekt dekorowany, bo sensowniejsze dla mnie jest podejście, że obiekt dekorowany to ten który przekazujesz do make, jakoś tak podświadomie to potraktowałem:
bo załóżmy przekazujemy tablicę $array do make($array)
i teraz ObjectToDecorate może zmienić nazwę pliku, rozszerzenie i rozmiar, więc modyfikuje tablicę (dekoruje), która jest w tym momencie obiektem dekorowanym/modyfikowanym. Dalsza dyskusja na temat dekoratora nie ma sensu naprawdę, bo rozumiem Twoje podejście, jednak niekoniecznie się z nim zgadzam. |
|
|
|
Post
#74
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Ponieważ zaczynasz bardziej sensownie pisać to jeszcze na to Ci odpowiem
Cytat To, czy Class2 traktujesz jako obiekt dekorowany, czy ostatni dekorator nie ma takiego znaczenia. Ma ogromne znaczenie, bo u Ciebie nie da się nawet wyciągnąć podstawowej funkcjonalności, może poza propertisami pliku ale to podobno ma być upload. To gdzie jest ten wspólny interfejs Cytat To nie jest dziedziczenie tylko przypisanie, co czyni ogromną różnicę. W programowaniu obiektowym mocno upraszczając obiekty, mogą albo po sobie dziedziczyć, albo może nastąpić ich kompozycja. Ty zrobiłeś kompozycje, ale ponieważ wszystkie te twoje klasy dziedziczą po tym samym interfejsie to zasadniczo zrobiłeś ich rozszerzenie wiec defakto uzyskałeś to samo jakby zrobić : Class : Class1 : Class2, efekt masz dokładnie identyczny, z tym że dla takiego podejścia bez problemu napiszesz testy automatyczne, dla Twojego już niekoniecznie. Bo to co ty zrobiłeś: Cytat Jest testowalne. Przetestowałem, działa, chociaż jest dość zawiłe w implementacj, jeszcze nad tym popracuję czyli test zero jedynkowy, działa nie działa to żaden dowód, że to zawsze tak będzie działać jakby się tego oczekiwało. Cytat Widzę, że wszędzie piszą tak jak Ty tutaj, rzuciłem okiem na ten wzorzec i jakoś mi umknęło to, że ostatni obiekt ma być traktowany jako obiekt dekorowany, bo sensowniejsze dla mnie jest podejście, że obiekt dekorowany to ten który przekazujesz do make ten obiekt który przekazujesz do make nie jest wgl z żadna z klas związany, to jest po prostu model na którym operujesz. Ani dekoratory ani klasa która dekorujesz wgl nie musza istnieć, żeby istniał ten objekt, a to może być cokolwiek. Cytat i teraz ObjectToDecorate może zmienić nazwę pliku, rozszerzenie i rozmiar, więc modyfikuje tablicę (dekoruje), która jest w tym momencie obiektem dekorowanym/modyfikowanym. Nadal nie rozumiesz co to jest dekorator, ten obiekt to model danych, jaki, taki jaki sobie wymarzysz. On wgl nie ma związku ze wzorcem dekorator. Cytat bo rozumiem Twoje podejście No właśnie nie rozumiesz, uwierz, że gdybyś stworzył dekorator nie potrzebowałbyś obserwatora który śledzi zmiany w poszczególnych klasach. Ja tego podejścia nie wymyśliłem, ja po prostu tłumacze Ci jak działa dekorator. Dekorator ma jedna jedyna definicje i jest to najprostszy z możliwych wzorców, ale jak się go nie zrozumie to wychodzi taki problem, że można uzyskać coś zupełnie innego. a wystarczyło napisać to tak z użyciem dekoratorów skoro tak bardzo to chciałeś zrobić:
No i które rozwiązanie jest bardziej akceptowalne te czy te:
Wgl spójrz ile zależności i klas potrzebujesz żeby stworzyć cokolwiek. Chcesz mieć rożne typy obsłużone, proszę bardzo:
Wiec nie:
A :
Chcesz mieć jakiś Encoder, nie ma problemu
Ten post edytował com 13.01.2017, 00:53:23 |
|
|
|
Post
#75
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Napisałeś praktycznie to samo co Ja, z tym, że u mnie jest rozbite na więcej mniejszych kroków...
Zdecyduj się, czy klasa ImageUpload pobiera parametr do konstruktora czy nie.
Poniżej jest pomniejszanie obrazu, czy generowanie obrazu z miniaturką?
Jak pobierzesz w Thumbnail informacje o pliku, skoro ImageUpload to klasa bazowa, która za pewne pobiera te dane? Chcesz w każdej klasie pobierać dane o pliku? Moje rozwiązanie startuje od klasy PropertyGet, żeby pobrało informacje o pliku raz, a później na nich bazowało. Gdzie pobierasz kontent pliku, gdzie go enkodujesz, jak chciałbyś zrobić zmianę nazwy? Taki uproszczony schemat to Ja też mogłem napisać w poście, ale jest bezużyteczny. Ten post edytował Omenomn 13.01.2017, 01:34:17 |
|
|
|
Post
#76
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Napisałeś praktycznie to samo co Ja, z tym, że u mnie jest rozbite na więcej mniejszych kroków... No właśnie, że nie bo ja nie potrzebuje u mnie nic więcej poza klasa bazowa i jej interfejsem, żeby stworzyć dowolny dekorator teraz. Cytat Zdecyduj się, czy klasa ImageUpload pobiera parametr do konstruktora czy nie. To nie ma znaczenia, jeśli potrzebujesz dodatkowe zależności to je dodajesz, co pokazałem, ale do tego jest inny wzorzec. Cytat Poniżej jest pomniejszanie obrazu, czy generowanie obrazu z miniaturką? Generowanie miniaturki, ale wystarczy zmienić ten dekorator na inny i masz inne zadanie. Cytat Jak pobierzesz w Thumbnail informacje o pliku, skoro ImageUpload to klasa bazowa, która za pewne pobiera te dane? Chcesz w każdej klasie pobierać dane o pliku? Ale do czego Ci są potrzebne te dane? Zrobienie miniaturki nie wymaga niczego więcej jak tylko pliku na którym ma zostać to wygenerowane. Cytat Taki uproszczony schemat to Ja też mogłem napisać w poście, ale jest bezużyteczny. To nie jest uproszczony schemat tylko pełna funkcjonalność taka sama jak u Ciebie. Implementacja:
Cytat Poniżej jest pomniejszanie obrazu, czy generowanie obrazu z miniaturką? Ok nazwa była zła zmienię na GenerateWithThumbnail Ten post edytował com 13.01.2017, 11:45:47 |
|
|
|
Post
#77
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
To co zrobiłeś jest sztywne i kompletnie nie rozszerzalne, chyba, że za każdym razem jak chcę coś dodać, będę musiał modyfikować konstruktor klasy ImageUpload i jej metodę upload() co jest bez sensu, dodatkowo wtedy musiałbym modyfikować kod wszędzie tam gdzie ta klasa jest używana.
Cytat Ale do czego Ci są potrzebne te dane? Zrobienie miniaturki nie wymaga niczego więcej jak tylko pliku na którym ma zostać to wygenerowane. Wegenerowanie pliku wymaga: - nazwy pliku, - ścieżki - kontentu wygenerowanego ze ścieżki - ścieżki na którą ma zostać zapisany. Wszystkie te dane należy wyciągnąć z pliku, żeby go przesłać, oprócz ścieżki do zapisu. Jeżeli ImageUpload pobiera te dane, to w jaki sposób dostanie je GenerateWithThumbnail, żeby mogło zmodyfikować plik i w jaki sposób prześle zmodyfikowany plik do ImageUpload. Pliku z requesta nie da się modyfikować, można co najwyżej zapisać zmodyfikowane dane o pliku i przesłać je dalej do obróbki, więc tak czy siak format przesyłanych danych się zmienia, a klasa bazowa ImageUpload musi je przyjąć. Kod $propeties->name = $file->getClientOriginalName(); $propeties->extension = $file->getClientOriginalExtension(); $propeties->path = $file->getRealPath(); $propeties->disk = '/uploadFolder/'; Jeżeli te dane wyciągniesz z file w ImageUpload to w jaki sposób dostanie je GenerateWithThumbnail i w jaki sposób encoder i renamer przekaże dane do GenerateWithThumbnail ze zmienioną nazwą i zmienionym rozszerzeniu. Najpierw powinna zostać wygenerowana miniatruka później plik bazowy, bo co jeśli chcę po prostu pomniejszyć plik, a nie generować dwóch? Najpierw muszę go pomniejszyć, a później wygenerować. Natomiast jeżeli masz podstawową kompozycję z trzech klas: Kod $file = new GetProperty(new GetContent(new Put))); $file->make($request->file); to wtedy bez problemowo można tworzyć nakładki bez jakichkolwiek modyfikacji wnętrzna klas już istniejących, przykładowo: Kod $file = new GetProperty(new Rename(new ToThumbnailResize(new GetContent(new Put)))); $file->make($request->file); lub Kod $file = new GetProperty(new Rename(new GenerateWithThumbnail(new GetSizeOfImage(new PutToSission(new GetContent(new Put)))))))); $file->make($request->file); w ten sposób bazę trzech klas można rozszerzać jak się chce, trzymając się jedynie kolejności klas bazowych, bo taki kod też będzie działał: Kod $file = new GetProperty(new PutToSession(new GenerateWithThumbnail(new GetSizeOfImage(new Rename(new GetContent(new Put)))))))); $file->make($request->file); tylko, że do sesji nie zostanie zapisana informacja o miniaturce, bo jest wygenerowana po zapisaniu danych do sesji. Jest to o wiele bardziej elastyczne rozwiązanie niż Twoje według mnie, nadbudowujące kod, a nie modyfikujące go. Teraz tak sobie pomyślałem, że w sumie do dekoratora nie musi być plik przekazywany, a może być obiekt: Kod $object->name; $object->extension; $object->content $object->saveDisk i wtedy klient dziedziczący po klasie abstrakcyjnej metodę do utworzenia takiego obiektu wywoływałby dekorator. Kod $client = new Image $client->make($request->file); Klient pobiera plik, a w metodzie make, lub w konstruktorze klienta byłoby Kod class Image extends ClientAbstract { protected $dekorator; public function __construct() { $this->decorator = new ImageUpload(); } public function make($file) { $object = stdClass; $object->name = $file->getName(); $object->content= $file->getContent(); $object->saveDisk= '/saveDisk/; $this->decorator->make($object); } } i wtedy kolejność dekoratorów nie ma żadnego znaczenia, bo można zrobić sam: Kod new ImageUpload() lubKod new Rename(new ImageUpload()); Kod new Rename(new Resize(new ImageUpload))) Co sądzicie? Ten post edytował Omenomn 13.01.2017, 14:32:15 |
|
|
|
Post
#78
|
|
|
Grupa: Zarejestrowani Postów: 37 Pomógł: 9 Dołączył: 14.09.2016 Skąd: Śląskie Ostrzeżenie: (0%)
|
|
|
|
|
Post
#79
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Wydaje Ci się (IMG:style_emoticons/default/biggrin.gif)
|
|
|
|
Post
#80
|
|
|
Grupa: Zarejestrowani Postów: 965 Pomógł: 285 Dołączył: 19.06.2015 Skąd: Warszawa Ostrzeżenie: (0%)
|
A mnie zastanawia, po co w ogóle zadajesz pytania @Omenomn, skoro później olewasz wszystkie odpowiedzi upierając się przy swoim? Zupełnie jak tutaj: http://forum.php.pl/index.php?showtopic=243138 :/
Ten post edytował kapslokk 13.01.2017, 15:54:18 |
|
|
|
Post
#81
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
To się zastanawiaj dalej, możemy gadać o php, a nie o mnie i moim podejściu do Waszych wypowiedzi.
Przedstawiłem nowy pomysł rozwiązania, więc się do niego odnieście, a nie do mnie. Co Wy jesteście, wyrocznia, że mam Wasze oceny i opinie przyjmować jako jedyne prawdziwe i niezaprzeczalne? Dyskutować można, a to co się wyciągnie z dyskusji to prywatna sprawa każdego z osobna. Tacy świetni jesteście, a jak com, albo daro0 wrzucili swój kod, to się okazuje, że gorzej przemyślany niż mój. Ten post edytował Omenomn 13.01.2017, 17:04:30 |
|
|
|
Post
#82
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat To co zrobiłeś jest sztywne i kompletnie nie rozszerzalne, chyba, że za każdym razem jak chcę coś dodać, będę musiał modyfikować konstruktor klasy ImageUpload i jej metodę upload() co jest bez sensu, dodatkowo wtedy musiałbym modyfikować kod wszędzie tam gdzie ta klasa jest używana. Nie ma takiej potrzeby bo klasa ImageUpload nigdy się nie zmieni, po to masz przecież dekorator żeby dodać do niej nowe funkcjonalności bez zmiany tej klasy. Te parametry które tam dostaje w konstruktorze one są stałe i nie maja znaczenia, równie dobrze możesz tam przekazać sam Encoder, a Renamer może być dekoratorem, bo w zasadzie zmieniasz źródło danych. Ja po prostu założyłem , że to jest podstawowa funkcjonalność i te kroki są wykonywane zawsze. Klasa mogła nie otrzymywać wgl parametrów i wszystko to dziać się w jej wnętrzu ale wtedy łamiesz zasady programowania obiektowego. Cytat Wegenerowanie pliku wymaga: - nazwy pliku, - ścieżki - kontentu wygenerowanego ze ścieżki - ścieżki na którą ma zostać zapisany. Wszystkie te dane należy wyciągnąć z pliku, żeby go przesłać, oprócz ścieżki do zapisu. No i co mi po tych danych, owszem potrzebuje je w klasie ImageUpload, która zapisuje mi przesłany plik, ale to już nie interesuje GenerateWithThumbnail, bo jego jedynym zdaniem jest stworzenie miniaturki, wiec do czego tu potrzebne są te inne informacje. Cytat Jeżeli te dane wyciągniesz z file w ImageUpload to w jaki sposób dostanie je GenerateWithThumbnail i w jaki sposób encoder i renamer przekaże dane do GenerateWithThumbnail ze zmienioną nazwą i zmienionym rozszerzeniu. Najpierw powinna zostać wygenerowana miniatruka później plik bazowy, bo co jeśli chcę po prostu pomniejszyć plik, a nie generować dwóch? Najpierw muszę go pomniejszyć, a później wygenerować. Jak chcesz coś pomniejszyć skoro to coś nie istnieje. Najpierw musisz mieć coś co będziesz zmniejszał a potem możesz to zmniejszyć, a nie najpierw zmniejszyć a potem dopiero to stworzyć. Sadze, że nadal nie stworzyłes dekoratora bo nie rozumiesz dalej czym on jest i rozwiązanie które powstało jest strasznie nie elastyczne i wgl nie testowalne. Cytat Tacy świetni jesteście, a jak com, albo daro0 wrzucili swój kod, to się okazuje, że gorzej przemyślany niż mój. Ja wrzuciłem kod dekoratora bo się na niego uparłeś, wiec skoro według Ciebie rozwiązanie jest złe to znaczy że dekorator nie był dobrym pomysłem i tyle Implementacja wersja 2:
Ten post edytował com 13.01.2017, 18:14:01 |
|
|
|
Post
#83
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Cytat No i co mi po tych danych, owszem potrzebuje je w klasie ImageUpload, która zapisuje mi przesłany plik, ale to już nie interesuje GenerateWithThumbnail, bo jego jedynym zdaniem jest zmiana rozmiaru obrazka, do czego tu potrzebne są te inne informacje. żeby zmienić rozmiar obrazka, musisz przekazać kontent pliku klasie GenerateWithThumbnail Cytat Jak chcesz coś pomniejszyć skoro to coś nie istnieje. Najpierw musisz mieć coś co będziesz zmniejszał a potem możesz to zmniejszyć, a nie najpierw zmniejszyć a potem dopiero to stworzyć. Przed uploadem plik znajduje się folderze z plikami tymczasowymi, jak nie wiesz takich rzeczy to o czym my rozmawiamy w ogóle? Na tym pliku się operuje, chyba, że chcesz najpierw go wysłać, a później obrabiać, co jest bez sensu, bo można to zrobić przed wysłaniem. Cytat Te parametry które tam dostaje w konstruktorze one są stałe i nie maja znaczenia, równie dobrze możesz tam przekazać sam Encoder, a Renamer może być dekoratorem, bo w zasadzie zmieniasz źródło danych. W ogóle parametry w konstruktorze nie mają znaczenia, zupełnie... Cytat Sadze, że nadal nie stworzyłes dekoratora bo nie rozumiesz dalej czym on jest i rozwiązanie które powstało jest strasznie nie elastyczne i wgl nie testowalne. Jest elastyczne, bo można nakładać warstwy jak się chce i jakie się chce, a klasa ImageUpload działa samoistnie bez żadnego dekoratora, tak jak chciałeś i oczywiście jest testowalne, bo znowu przetestowałem i działa w różnych konfiguracjach. Dajmy sobie spokój, bo to co przedstawiasz po prostu nie może działać, jest nieścisłe, ogólne, nierozszerzalne i nietestowalne i proszę Cię skończ mi wmawiać, że nie rozumiem dekoratora. Ten post edytował Omenomn 13.01.2017, 17:45:33 |
|
|
|
Post
#84
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat żeby zmienić rozmiar obrazka, musisz przekazać kontent pliku klasie GenerateWithThumbnail Niczego nie musisz przekazywać bo ta klasa otrzyma surowy plik. Cytat Przed uploadem plik znajduje się folderze z plikami tymczasowymi, jak nie wiesz takich rzeczy to o czym my rozmawiamy w ogóle? Na tym pliku się operuje, chyba, że chcesz najpierw go wysłać, a później obrabiać, co jest bez sensu, bo można to zrobić przed wysłaniem. No wiec ten plik istnieje w tempie, a nie Ty go dopiero tworzysz potem. Cytat W ogóle parametry w konstruktorze nie mają znaczenia, zupełnie... No nie mają, bo to są zależności potrzebne klasie ImageUpload, tam może być cokolwiek Cytat Jest elastyczne, bo można nakładać warstwy jak się chce i jakie się chce, a klasa ImageUpload działa samoistnie bez żadnego dekoratora, tak jak chciałeś i oczywiście jest testowalne, bo znowu przetestowałem i działa w różnych konfiguracjach. Tak ale tylko w ściśle określonej kolejności i żadnego nie można pominąć. Zacznijmy od tego, że nawet nie wiesz co są testy, wiec nie rozumiesz tego, że to nie działa. Masz nieskończona ilość kombinacji i co przetestowałeś je wszystkie, nie, zrobiłeś testy działa nie działa, a to nie jest testowalność. Cytat Dajmy sobie spokój, bo to co przedstawiasz po prostu nie może działać, jest nieścisłe, ogólne, nierozszerzalne i nietestowalne i proszę Cię skończ mi wmawiać, że nie rozumiem dekoratora. No nie rozumiesz bo mimo wielu prób dekorator nie powstał, ale tak zakończmy to, wróć za parę lat z doświadczeniem (IMG:style_emoticons/default/smile.gif) Ten post edytował com 13.01.2017, 18:02:00 |
|
|
|
Post
#85
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Nie kpij sobie, doświadczeniem nie nadrobisz kumatości.
Dakorator powstał. Mam to gdzieś, czy nazwiesz to dekoratorem, modyfikatorem, warstwami, czy jeszcze jakoś inaczej, ważne, że porządkuje kod. |
|
|
|
Post
#86
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Nie kpij sobie, doświadczeniem nie nadrobisz kumatości. Dakorator powstał. Mam to gdzieś, czy nazwiesz to dekoratorem, modyfikatorem, warstwami, czy jeszcze jakoś inaczej, ważne, że porządkuje kod. Owszem nie nadrobisz, ale to nie ja nie kumam jak działa dekorator tylko Ty go nie zrozumiałeś. A twój kod nie został uporządkowany, a bardziej zaciemniony niż jakbyś zrobił po prostu wszytko w kontrolerze i tyle (IMG:style_emoticons/default/wink.gif) |
|
|
|
Post
#87
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Szaleństwo! Najlepiej piszmy apki w jednym pliku i jednej klasie (IMG:style_emoticons/default/biggrin.gif)
Ten post edytował Omenomn 13.01.2017, 18:16:44 |
|
|
|
Post
#88
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Zróbmy tak, wrzuć całą swoja implementacje na gita i daj linka. Specjalnie dla Ciebie zrobię z tego dekorator (IMG:style_emoticons/default/smile.gif)
Cytat Najlepiej piszmy apki w jednym pliku i jednej klasie Bardzo skrajne rozwiązanie, ale istnieje takie coś jak Zasada Keep It Simple, Stupid (czyli tłumacząc: nie komplikuj, głupku) jest to reguła mówiąca, że nie należy na siłę komplikować prostych rzeczy, aby przykładowo wykorzystać niepotrzebne w danym momencie wzorce projektowe. |
|
|
|
Post
#89
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Ok wrzucę, może ktoś się czegoś nauczy.
https://github.com/omenomn/uploadDecorator Masz, ciekawe jak to poprawisz. Ten post edytował Omenomn 13.01.2017, 18:33:43 |
|
|
|
Post
#90
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
@Omenomn
Zanim zaczniesz jechać po czyimś kodzie czy tam w ogóle podejściu (i nie mówię o swoim) to tak: 1. Napisz jakiś serwis pokroju tego forum albo coś innego, co się wiąże z kilkumiesięcznym nakładem pracy 2. Napisz kolejny serwis za rok i wróć do kodu sprzed roku 3. Napisz coś kolejnego za 2 lata, za 3 itd.. i znowu wróć Gwarantuję Ci że będziesz miał niesmak po tym co zrobiłeś wcześniej. Akurat @com przedstawił tu dość klarowne rozwiązanie, łatwe do zrozumienia a konkretniej chodzi o to na czym polega i co się dzieje po zastosowaniu wzorca dekorator. Podałem tylko wcześniej pewną realizację wczytywania zdjęć modułem Image z Kohany i ich obróbkę na podstawie parametrów z request query, podaj może tutaj praktyczną realizację jak byś zrobił taki static server, który w zależności od parametrów z paska przeglądarki wyświetlałby odpowiednio udekorowane zdjęcia na bazie swojego rozwiązania. |
|
|
|
Post
#91
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Po moim jadą wszyscy cały czas (IMG:style_emoticons/default/biggrin.gif)
Wrzuciłem link na github. Coś długo te poprawki (IMG:style_emoticons/default/biggrin.gif) Ten post edytował Omenomn 13.01.2017, 21:15:38 |
|
|
|
Post
#92
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Coś długo te poprawki Bo tam w tym kodzie niczego się nie dało wykorzystać, no może poza tym co jest gotowe czyli wykorzystanie FFMpeg. I wcale nie powiedziałem, że dam Ci to od razu, przecież cały czas nie siedziałem nad tym rozwianiem, robię inne rzeczy o wyższym priorytecie niż ten kod. https://github.com/ComStudio/decorator Ten post edytował com 13.01.2017, 23:43:48 |
|
|
|
Post
#93
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Gdzie Ty tam masz ten Twój niezrozumiały przeze mnie dekorator, bo nie widzę tam ani jednej klasy wywołanej w konstruktorze innej?
I w czym niby Twój kod jest lepszy od mojego? info o pliku pobierasz w trzech, albo więcej miejscach:
Nawet nie chce mi się już analizować tego kodu, burdel taki, że głowa boli. |
|
|
|
Post
#94
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Gdzie Ty tam masz ten Twój niezrozumiały przeze mnie dekorator, bo nie widzę tam ani jednej klasy wywołanej w konstruktorze innej? https://github.com/ComStudio/decorator/blob/master/index.php Tu masz wywołanie. Cytat info o pliku pobierasz w trzech, albo więcej miejscach: A tu co niby robisz https://github.com/omenomn/uploadDecorator/...sformers/Makers W każdej klasie zwracasz 95% tych samych informacji. Ja tam niczego nie pobieram, poza klasa File, w pozostałych miejscach tylko zwracam te informacje, żeby wygenerować nowy plik z miniaturka na bazie oryginału. W dodatku te dwie metody save to przecież dwie rożne klasy, jedna dla Image, druga dla Video. Ten fragment to tworzenie nowego obrazka, czyli tej miniaturki, bo coś źle chyba to zrozumiałeś.
Moje File to Twoje: https://github.com/omenomn/uploadDecorator/...kerAbstract.php Klasa abstrakcyjna ma co najmniej jedna metodę abstrakcyjna, inaczej nie jest klasą abstrakcyjną, wiec nie ma sensu. A tu to już wgl szaleństwo https://github.com/omenomn/uploadDecorator/...s/Puter.php#L11 Potrafisz stworzyć obiekt klasy abstrakcyjnej. Aż dziw że ten kod działa (IMG:style_emoticons/default/aarambo.gif) Cytat Nawet nie chce mi się już analizować tego kodu, burdel taki, że głowa boli. Burdel to masz w swoim kodzie, widać, że nawet nie używasz porządnego IDE, bo masz masę rzeczy które są zbędne i albo nigdzie nie używasz. Skoro te rozwiązanie jest dla Ciebie nie zrozumiałe, to nie mamy o czym rozmawiać, bo nie potrafisz pisać jeszcze obiektowo. Za parę lat jak wrócisz i się tego nauczysz to wtedy zrozumiesz to co stworzyłem (IMG:style_emoticons/default/smile.gif) Twój kod to idealny przykład jak tego nie robić (IMG:style_emoticons/default/smile.gif) Utrzymanie takiego kodu jaki stworzyłeś już dziś jest problematyczne. Nie mówiąc już o zrozumieniu jego, bo z niego nie wynika nic co chciałeś tam zrobić i jak ktoś dostanie ten kod to będzie się bał wgl to ruszyć (IMG:style_emoticons/default/smile.gif) Polecam lekturę CzystyKod. Ten post edytował com 14.01.2017, 01:16:27 |
|
|
|
Post
#95
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Ciekawe jak zapiszesz plik bez zapisywania informacji o nim do sesji, skoro klasa Upload wymaga interjejsu StorageInterface. Gdzie masz kodowanie, zmianę nazwy randomową i do ustawienia? W dekoratorze używa się jednego interfejsu, a nie jak tutaj:
No chyba, że bazę traktujesz jako:
tylko po co ta sesja w konstruktorze? Cytat A tu co niby robisz https://github.com/omenomn/uploadDecorator/...sformers/Makers W każdej klasie zwracasz 95% tych samych informacji. To są transformery, one nie pobierają danych tylko transformują otrzymane dane do postaci jaką się potrzebuje. Działają na pojedynczym elemencie i kolekcji. Cytat A tu to już wgl szaleństwo https://github.com/omenomn/uploadDecorator/...s/Puter.php#L11 Potrafisz stworzyć obiekt klasy abstrakcyjnej. Aż dziw że ten kod działa aarambo.gif Nie tworzę obiektu klasy abstrakcyjnej tylko jej interfejsu. Klasa abstrakcyjna działa jak interfejs z tym, że metody możesz w niej dodawać. Przykłady wywołania mojego kodu:
Który kod jest bardziej elastyczny? Odpowiedź jest chyba oczywista. Ogólnie rzecz biorąc problem nie jest tak oczywisty do rozwiązania i błachy, jak wydaje mi się, że go większość potraktowała. Ten post edytował Omenomn 14.01.2017, 06:02:35 |
|
|
|
Post
#96
|
|
|
Grupa: Zarejestrowani Postów: 88 Pomógł: 12 Dołączył: 17.09.2014 Skąd: Krasnystaw Ostrzeżenie: (0%)
|
Pod Laravela jest coś interesującego np. do obróbki zdjęć a i z uploadem sprawa powinna być prosta.
http://image.intervention.io/ Podobne podejście jak w Kohanie (gdzie jest moduł Image). http://www.easylaravelbook.com/blog/2015/0...with-laravel-5/ |
|
|
|
Post
#97
|
|
|
Grupa: Zarejestrowani Postów: 77 Pomógł: 0 Dołączył: 4.02.2014 Ostrzeżenie: (20%)
|
Wrzucałem już link do intervention image w tym temacie i pisałem, że go wykorzystuję.
Daro0 nie rozumiesz problemu, jeśli podrzucasz mi bibliotekę do obróbki zdjęć. Ona nie wykonuje uploadu, zmiany nazw plików, zapisu danych o plikach do sesji, wycinania miniaturek z video, czy innych czynności związanych ogólnie z plikami, a nie tylko z obrazami. Rozwiązanie, które przedstawiłem wykonuje wszystkie te operacje plus do tego jest całkowicie elastyczne, bo można dodawać poszczególne warstwy odpowiedzialne za kolejne operacje, bez ingerencji, w którąkolwiek warstwę już istniejącą, np. pobieranie wysokość i szerokość (wykorzystanie intervention image), albo rozmiaru pliku, czy innych właściwości. Mogę np. chcieć zmienić wielkość filmiku i wtedy po prostu dodaję warstwę odpowiedzialną za to. Jeśli nie widzicie plusów takiego rozwiązania to Ja nie wiem... ps. Jednak warto było mimo wszystko temat umieścić, bo pomysł z dekoratorem przyszedł mi po próbach szukania odpowiedniego wzorca zainspirowany odpowiedziami tutaj między innymi mrc, a ostateczny szlif dokonał się po uzmysłowieniu sobie, że klasa bazowa dekoratora powinna funkcjonować sama (com) |
|
|
|
Post
#98
|
|
|
Grupa: Zarejestrowani Postów: 37 Pomógł: 9 Dołączył: 14.09.2016 Skąd: Śląskie Ostrzeżenie: (0%)
|
Jako obserwator tematu dziwię się że com jeszcze chce z tobą dyskutować. Jego kod jest czytelny, samoopisujacy sie, zrozumiały dla osób postronnych (przynajmniej tych znających OOP). Wystarczyło mi 3 minuty na zrozumienie całości (może dlatego że sam bym to zaimplementował bardzo podobnie).
Twoj kod omenomn analizowałem 5 minut i zrezygnowałem. Nie ma tam dzbła KISS, jeszcze te nazwy klas (puter, returner) ... może i twoje rozwiązanie jest zrozumiałe dla ciebie i w twoim mniemaniu jest elastyczne, ale do cholery nie mógł bym pracować na twoim kodzie, bo jest po prostu zbyt skomplikowany. Ten post edytował rafkon1990 14.01.2017, 11:13:40 |
|
|
|
Post
#99
|
|
|
Grupa: Zarejestrowani Postów: 3 034 Pomógł: 366 Dołączył: 24.05.2012 Ostrzeżenie: (0%)
|
Cytat Ciekawe jak zapiszesz plik bez zapisywania informacji o nim do sesji, skoro klasa Upload wymaga interjejsu StorageInterface. Gdzie masz kodowanie, zmianę nazwy randomową i do ustawienia? Tam masz interfejs wiec zapisujesz do czegokolwiek co implementuje ten interfejs. Przecież nie zrobię Ci gotowca, ja tylko wskazałem drogę która masz iść, Zmiana kodowania,nazwy itd to będą kolejne dekoratory, które sobie dopiszesz w miarę potrzeb. Dekoratorem jest z tego fragmentu tylko:
Upload to klasa bazowa, a SessionStorage wgl nie ma znaczenia dla dekoratora. Bo to jest zależność wstrzykiwana do Upload, dlatego możesz wstawić dowolny storage jaki sobie wymarzysz, warunek jest tylko taki musi implementować zdefiniowany interfejs. Cytat To są transformery, one nie pobierają danych tylko transformują otrzymane dane do postaci jaką się potrzebuje. Działają na pojedynczym elemencie i kolekcji. Nie rozumiem wgl ich zastosowania, ale ja to wszytki zawarłem w jednej klasie File która działa dla wszystkich. Cytat Nie tworzę obiektu klasy abstrakcyjnej tylko jej interfejsu. Klasa abstrakcyjna działa jak interfejs z tym, że metody możesz w niej dodawać. Owszem klasa abstrakcyjna może posiadać definicje jakiś wspólnych metod ale musi posiadać co najmniej jedną metodę abstrakcyjną, żeby można było ja nazwać klasa abstrakcyjna, inaczej to jest zwykła klasa. To są podstawy programowania obiektowego. Cytat Który kod jest bardziej elastyczny? Odpowiedź jest chyba oczywista. Owszem jest, nie Twój i to nie jest moja tylko subiektywna opinia, ale reszta osób stwierdziła to samo. Nie wiem gdzie Ty pracujesz, czy robisz to sam czy w jakimś zespole ale jak w zespole to niech ktoś zrobi Ci code review tego co stworzyłeś (IMG:style_emoticons/default/smile.gif) |
|
|
|
Post
#100
|
|
|
Grupa: Zarejestrowani Postów: 8 068 Pomógł: 1414 Dołączył: 26.10.2005 Ostrzeżenie: (0%)
|
@com Co do abstrakcji to klasa abstrakcyjna nie musi zawierać metod abstrakcyjnych (IMG:style_emoticons/default/wink.gif) Za to każda klasa która posiada przynajmniej 1 abstrakcyjną metodą musi być abstrakcyjna.
Tak więc Kod abstract class Test { public function testing() { } } jest poprawne. |
|
|
|
![]() ![]() |
|
Aktualny czas: 23.12.2025 - 19:29 |