Modernizować, czy pisać od nowa?

0

Piszę, bo sam juz nie wiem. Jakieś pół roku temu w firmie w której pracuję, przed audytem potrzebny, był na gwałt program do monitoringu produkcji. Na jego napisanie miałem mniej niż miesiąc. Później były drobne upgrady. Problem polega na tym, że z braku czasu napisałem go dosyć topornie. Brak uniwersalnych klas, silnika bazy danych i <ort>w ogóle</ort> lipa. Program działa ok, ale jego konserwacja to koszmar. Teraz mam czas na pisanie nazwijmy "v2.0", ponieważ pierwszy działa. I tu pytanie. Czy zmodernizować to co już mam, czy na podstawie pierwszego napisać następcę. Ja poszedłbym w myśl prawa Murphy'ego: "Jeżeli coś zostało źle zrobione od samego początku, wszelkie próby ort! tylko to pogorszą".

Jeżeli mozecie wypowiedzieć się w tej kwestii, to będę zobowiązany.

0

Chyba trudno cos powiedziec.
Nie znamy objetosci i zlozonosci tego programu. Totez nie mozemy okreslic stosunku czasu do efektu jaki daloby napisanie tego od nowa.

Ale jesli program ma sluzyc wiele lat to moze warto poswiecic kilka dni. Moze calkiem sporo kodu da sie przeniesc do nowej wersji. Ale to musisz ocenic Ty.

0

ja już miałem taką sytuację, postanowiłem napisać program od nowa, i tak przy niektórych sprawach zniechęciła mnie myśl pisania jakiejś funkcji od nowa, w rezultacie przeniosłem ogromne płachty kodu i można powiedzieć że jeszcze bardziej pogorszyłem sprawę ;P

0

Ja również mam poprzeklejane połacie kodu, co powoduje, że już się w nim gubię. Na sugestię Codera dokładniejszy opis zagadnienia i skali problemu (program ma około 9000 wierszy i rośnie):

Program słuzy do monitorowania produkcji. Dane wprowadzam do tabeli:
user image
Dzięki temu mam opisaną jedną zmianę. Szefa interesują głownie statystyki typu: ile dobrych, jakie błędy najczęściej, który operator najgorszy itp. I tu się pijawia powielanie fragmentów, bo wykresy tworzę wg:
1). Operator
2). Brygada
3). Miesiąc
4). Powierzchnia wystąpienia błedu
5). Maszyna

Różnią się tylko kwerendą. Graficzna reprezentacja jest taka sama, czyli:
user image
user image
user image

Na rapidshare zamieściłem jeden moduł liczący wg operatora: NameSheet

0

Ja bym sie zastanowil czy nie wykorzystac do tego PHP i MySQL bo imo to srodowisko stworzone do tego typu rzeczy :)

0

Z własnego doświadczenia powiem Ci, że lepiej będzie gdy napiszesz program od nowa. Zrób mały plan co i jak ma działać i możesz nawet przekopiowac niektóre części starego programu byle pasowały do obranego schematu ( oczywiście tam gdzie to możliwe ). Moje próby poprawienia programu napisanego byle jak zwykle skutkowały wystąpieniem większego problemu - coś gdzieś zostało zmienione i nie współdziałało z resztą a żeby znaleźć to coś trzeba było się troszkę nagłowić. Mimo to wydaje mi się, że tworzenie oprogramowania to sprawa indywidualna, bo każdy ma swoje nawyki i przyzwyczajenia. Dlatego najlepiej żebyś sięgnął pamięcią wstecz i przypomniał sobie czy kiedykolwiek miałeś już taki problem.

0

Miałem. I zastosowałem prawo Murphi'ego: "Jeżeli coś zostało źle zrobione od samego początku, wszelkie próby naprawienia tylko to pogorszą" Prace nad nowym programem zostały rozpoczęte. Do posta można się nie dopisywać. Odpowiem na swoje pytanie: Pisać od nowa. Dzięki za zainteresowanie. Pozdrawiam. Adam.

0

Ja bym sie zastanowil czy nie wykorzystac do tego PHP i MySQL bo imo to srodowisko stworzone do tego typu rzeczy :)

Oleksy_Adam napisał(a)

" Program działa ok, ale jego konserwacja to koszmar. "

Jesli nie chcesz mieć w przyszłości podobnych problemów raczej nie pisz tego w php, jesli zacząłeś to masz czas by to zmienić.
To oczywiście moja subiektywna mało popularna opinia.

pzdro

0

Póki co to piszę bazę na własnym formacie, jestem na etapie nauki MySql i dbExpress. Wersja v3.0 będzie już w dbE.

0

Co do rozwijania programu to mialem taka sytuacje ostatnio ze dostalem aplikacje, ktora powstawala iles tam tygodni, miala pewne bugi, zero dokumentacji czy komentarzy w kodzie, zadnego planu, dziwne biblioteki i kod na kilka tysiecy lini... dwa tygodnie implementowalem rozszezona funkcjonalnosc, gdzie meczylem sie przy tym niemilosiernie... oczywiscie okazalo sie ze dalej sa jakies bug'i i przez tydzien ich szukalem z mizernym rezultatem (aplikacja walila sie w losowych momentach)... sie zdenerwowalem i udalo mi sie napisac wszystko od nowa w dwa tygodnie w C#, gdzie wszystko jest jasne i przejrzyste, udokumentowane i ze schemacikami i co najwazniejsze, dziala. Wiec przystaje raczej do tego, ze czasami szybciej cos napisze sie od nowa niz modyfikuje stare i nie do konca dobre rozwiazania...

0

Panie Adamie
Ja się z Waszego grona wybiję i napiszę, że zdecydowanie lepiej jest poprawić swój kod (w znaczeniu np. zoptymalizować go) niż napisać od początku. W pierwszym swoim poście napisał pan, że szef wymaga teraz wersji 2.0 tego programu. Jeżeli rozpocznie pan prace ad novo to tak naprawdę nie będzie to wersja 2.0 ale wersja 1.0 całkiem nowego programu z nowymi błędami.

Ja mam taką naturę i taką już rozwiniętą intuicję, że optymalizuję kod w trakcie pisania algorytmu zanim zostanie on jeszcze ukończony.

Proszę zauważyć, że jeżeli będzie pan kopiować kod z jednego pliku do drugiego to skopiują się także błędy, a skoro program będzie działał błędy zostaną niezauważone. I problem się powtórzy. Jeżeli natomiast prześledzi pan swój program linijka po linijce to nie tylko usprawni pan silnik, złożoność algorytmów czy szybkość wykonywania (zauważy pan z pewnością: ?o? ta pętla jest tu przecież niepotrzebna? albo ?niepotrzebnie napisałem funkcję która sprawdza ten warunek. Przecież ten warunek jest już wykluczony przez poprzednią funkcję.?) ale znajdzie pan wiele błędów, a co najważniejsze nie przepisze pan programu z, nazwijmy to, usterkami. Jedyne co pan będzie robił to znajdywał i likwidował błędy, poprawiając przy tym jakość działania samego programu.

A na koniec proszę zauważyć jedną ważną rzecz. Gdy zacznie pan poprawiać swój program to nie tylko napisze pan jego lepszą wersje ale też sam rozmiar się skróci. Jeżeli zacząłby pan kopiować kod z jednego pliku do drugiego i jeszcze mając nadzieję na ulepszenie programu, to nie tylko wprowadzi pan jeszcze więcej błędów ale kod stanie się jeszcze dłuższy, a jak wcześniej pan napisał kod już i tak ma bagatela ponad 9000 linii. Czy to ma sens? Panie Adamie? zrobi pan jak zechce ale proszę się zastanowić.

Zawsze powtarzam czy to studentom czy też każdemu kto o to zapyta, że analizowanie swojego kodu i poprawianie go uczy wspaniałej sztuki jaką jest umiejętność optymalizowania kodu. A tego się niestety nie da nauczyć ciągle pisząc programy od nowa.

0

Pouczająca wypowiedź. Pisząc nową wersję opierałem się ściśle na poprzedniej. Idea była taka, że porawiając klasę miałem obok siebie starą i czysty plik. W wielu przypadkach było to dosłownie przepisywania. Przeanalizowałem v1.0 dosłownie linia po linii i pisałem wersję v2.0. I tu się zgodzę, bo trzy razy wieksza baza ma dwa razy taki sam rozmiar i działa minimalnie szybciej niż jej poprzedniczka. I tu w dobie wyjaśnienia. Sam algorytm zapis, odczyt dodawanie rekordów pozostał niezmienioby (bo działał). Dodałem minimalną optymalizację (głównie jesli chodzi o pamięć). Problem był podczas generowania raportów z owej bazy i tu właśnie pisałem "od nowa". Opracowałem szybki silnik do generowania różnego rodzaju raportów. Maksymalnie wykorzystałem podobieństwa w kwerendach filtrujących aby nie musieć pisać 2x tego samego. Stara wersja służyła za podkładke. Dobrym porównaniem bedzie:

v 1.0 -> Rysunek techniczny na poplamionej kalce.
v 2.0 -> Ten sam rysunek, tylko przerysowany na czystą kalkę.

0

Zgodze sie, ze moze i racja jesli pisze sie wersje 2.0 swojego programu. Ale jesli dostalo sie program do przejecia i rozwiania, bez zadnej dokumentacji czy opisow, dziesiatki funkcji, ktorych dzialanie jest niejasne i wiadome jest ze program zawiera duza ilosc bug'ow to tutaj mozna pokusic sie o przepisanie. Plusy tego sa takie, ze mozemy wszystko ladnie udokumentowac i miec rozeznanie w kodzie (zwlaszcza jesli w przyszlosci to wlasnie my mamy zajmowac sie utrzymaniem aplikacji). Minusy sa oczywiste: prawdopodobnie mozemy popelnic te same bledy, jak i nienadaje sie to zupelnie do wiekszych projektow. Jednakze przy mniejszych projektach uwazam, ze sledzenie linijka po linijce cudzego kodu, gdzie nawet zmienne nie sa nazwane odpowiednio tylko np zmienna a,b,c & magic numbery ktore cos robia w jakiejs petli, mija sie z celem i naprawde lepszym rozwiazaniem jest przepisanie wszystkiego od nowa, pozadnie to dokumentujac na przyszlosc.
Co do optymalizacji i refactoringu, zawsze zostawiam to na sam koniec. Wazniejszy jest termin niz to czy aplikacja smiga, pozniej mozna ja optymalizowac o ile zostanie na to troche czasu. Juz zdazylo mi sie, ze zawalilem termin, wlasnie przez to ze trzy razy poprawialem klase, ktora juz dzialala, ale chcialem zrobic to lepiej, a pozniej wyszly problemy, ktore zjadly mi nieco wiecej czasowego bufora niz zakladalem na starcie.

P.S. Rysunki techniczne w wersji finalnej najlepiej przerysowac do Visio i zalaczyc jako pliki projektu. Naprawde to ulatwia prace w przyszlosci :)

0
<font size="2"> > ##### wasiu napisał(a) > Zgodze sie, ze moze i racja jesli pisze sie wersje 2.0 swojego programu. Ale jesli?

</span><font size="4">wasiu</span><font size="2">? z pełnym szacunkiem do Ciebie i Twojej umiejętności programowania, ale Ty chyba nie byłeś w pełni świadomy tego co piszesz. Przeczytaj swój post parę razy, oczywiście ze ZROZUMIENIEM!

wasiu napisał(a)

jesli dostalo sie program do przejecia i rozwiania?

Możesz to napisać po polsku? Rozumiem, ze miałeś na myśli: jeżeli przejęło się cudzy projekt jakiegoś programu w celu usunięcia błędów i analizy składni.

wasiu napisał(a)

bez zadnej dokumentacji czy opisow, dziesiatki funkcji, ktorych dzialanie jest niejasne i wiadome jest ze program zawiera duza ilosc bug'ow to tutaj mozna pokusic sie o przepisanie.

Przecież to jakaś paranoja! Jeżeli wiadomym jest, że program nie ma dokumentacji, funkcje w nim użyte są trudne w analizie i napisany jest z błędami to chcąc świadomie go przepisywać pamiętaj, ze świadomie również przepisujesz i błędy i funkcje bez zrozumienia ich działania a w konsekwencji uniemożliwiasz napisanie sobie dokumentacji do tego programu (w szczególności dokumentacji tych dziesiątków funkcji). Jeżeli chce się program (i zawarte w nim funkcje) zrozumieć (z znaczeniu zrozumieć ich algorytmy działania) to TRZEBA zanalizować KAŻDĄ funkcję i KAŻDĄ linijkę programu! Tylko w ten sposób zrozumiesz program i będziesz mógł napisać do niego dokumentację.

wasiu napisał(a)

Plusy tego sa takie, ze mozemy wszystko ladnie udokumentowac i miec rozeznanie w kodzie (zwlaszcza jesli w przyszlosci to wlasnie my mamy zajmowac sie utrzymaniem aplikacji).

Jeżeli przepiszesz bez zrozumienia bo np., nie będziesz mieć chęci, czasu albo kod okaże się zbyt skomplikowany jak na Twoją wiedzę to jak zrozumiesz algorytmy użyte w funkcjach a tym samym jak zrozumiesz ich działanie? NIE ZROZUMIESZ! I dlatego NIE NAPISZESZ dokumentacji (przynajmniej całkowitej i szczegółowej) i dlatego to jest duży MINUS a nie plus!!! Przeczytaj jeszcze raz to co wcześniej napisałem.

wasiu napisał(a)

Minusy sa oczywiste: prawdopodobnie mozemy popelnic te same bledy, jak i nienadaje sie to zupelnie do wiekszych projektow.

Co do pierwszej części się zgodzę. Przepisywanie żywcem funkcji z błędami to minus. Ale co do drugiej już nie. Przepisywanie tego rodzaju programów nie nadaje się nie tylko do dużych projektów. Takie postępowanie nie nadaje się do WSZYSTKICH projektów. Argumenty patrz wyżej.

wasiu napisał(a)

Jednakze przy mniejszych projektach uwazam, ze sledzenie linijka po linijce cudzego kodu, gdzie nawet zmienne nie sa nazwane odpowiednio tylko np zmienna a,b,c & magic numbery ktore cos robia w jakiejs petli, mija sie z celem

I znów to samo. Herezja. Jeżeli program jest mały i ma, np. 500 linijek kodu to o wiele szybciej się go przeanalizuje i wykryje błędy (być może nawet wszystkie za pierwszym razem) niż w programie który składa się, np. z 10 000 linijek kodu i jeszcze w dwudziestu różnych plikach. Ja sam osobiście jeżeli muszę zastosować jakąś pętlę i potrzebna mi jest zmienna to nazywam je zwykle a, b, c lub i (najczęściej bo pochodzi od słowa indeksować). Nie ma sensu nazywać przecież takiej zmiennej np. zmiennaZliczajacaPowtorzeniaWPetli A co do nazywania zmiennych to pewnie nie wiesz ale w niektórych językach programowania np. w AS (ActionScript) długość zmiennych MA ZNACZENIE na szybkość wykonywania programu. Taką po prostu ten język ma implementację, że odczytanie zmiennych o długich nazwach trwa odpowiednio dłużej. Poczytaj sobie o specyfikacji ECMA-262 (Język AS jest zrobiony w oparciu o tą specyfikację).

wasiu napisał(a)

Co do optymalizacji i refactoringu, zawsze zostawiam to na sam koniec.

Można zostawić a można od razu. Przypuśćmy, że mamy instrukcję warunkową która musi wykonać pewną instrukcję jeżeli zmienna a ma wartość 1, a gdy ma wartość 0 to ma wykonać inną instrukcję. Przyjmijmy, że zmienna a może przyjmować jedynie wartości 0 lub 1. To jeżeli widzę u studentów, np. taki warunek w instrukcji if:

if(a > 0) {
  intrukcja_pierwsza;
};
if(a == 0) {
  instrukcja_druga;
};

to aż się prosi aby od razu poprawić na:

if(a == 1) {
  intrukcja_pierwsza;
} else {
  instrukcja_druga;
};

albo jeszcze krócej:

if(a) {
  intrukcja_pierwsza;
} else {
  instrukcja_druga;
};

względnie:

if(a)
  intrukcja_pierwsza;
else
  instrukcja_druga;

albo już w ostateczności:

(a) ? instrukcja_pierwsza : instrukcja_druga;

Przecież nie trzeba z tym czekać, aż do ukończenia projektu.</span>

0
Joseph Louis Lagrange napisał(a)
wasiu napisał(a)

Co do optymalizacji i refactoringu, zawsze zostawiam to na sam koniec.

Można zostawić a można od razu.
...
Przecież nie trzeba z tym czekać, aż do ukończenia projektu.

Owszem, ze mozna od razu ale pozwole sobie opisac pewne swoje doswiadczenie. W tresci pewnego artykulu, ktory traktowal o optymalizacji, zostalem zachecony do tego, zeby za kazdym razem gdy przeprowadzi sie optymalizacje zmierzyc, czy przyniosla ona zamierzony efekt. W skrocie napisze tylko, ze rekurencja, ktora uwazana jest za zlo konieczne, w pewnym przykladzie okazala sie szybsza (!!!) od iteracji. Czasem metody optymalizacji przyniosly jedynie 5 - 10% wzrostu szybkosci dzialania programu. Tak wiec majac na wzgledzie to, co napisalem powyzej, jednak lepiej jest napisac na poczatku dzialajacy kod a pozniej go optymalizowac w miare posiadania wolnego czasu, bo czasem optymalizacja przeprowadzana w trakcie pisania kodu jest zbedna strata czasu.

0

@yacooh: Akurat fakt, że rekurencja jest szybsza od iteracji, to jest norma. Bo jest bardziej naturalna i wymaga w ogromie przypadków mniejszej ilości operacji. Podstawową wadą rekurencji jest ilość zużywanej pamięci, która faktycznie, często jest o wiele większa od tego samego zadania wykonanego iteracyjnie (napisałbym "zawsze", gdyby nie to, że od każdej reguły da się znaleźć wyjątek). A zło konieczne? Wręcz przeciwnie. Z punktu widzenia programisty jest to najczęściej idealna konstrukcja. Jasna i klarowna. Podczas gdy iteracja jest wynikiem działań mających na celu optymalizację pamięciową i najczęściej traci na przejrzystości.

0

@Adam, po raz pierwszy spotykam sie ze stwierdzeniem, ze rekurencja jest szybsza od iteracji :) to, ze jest bardziej naturalna nie ulega watpliwosci, ale czy szybsza? Wystarczy sie odrobine zastanowic...

Odgrzebalem ten artykul o ktorym pisalem i pozwole sobie przytoczyc to co powiedzial Michael Abrash (m.in. wspolpracowal z Cramackiem na silnikiem do I Quake'a). Sprawa dotyczyla przejscia przez drzewo. Zaprezentowane zostaly dwa algorytmy: rekurencyjny i iteracyjny i jak sam Abrash powiedzial "jestem bardzo zdziwiony tym, ze wersja iteracyjna dziala tylko 20% szybciej bez wlaczonej optymalizacji." Tak wiec nie tylko ja uwazam, ze rekurencja jest w normalnym uzyciu "drozsza" od iteracji.

0

Wszystko zależy od tego, co trzeba dorabiać, żeby iteracja wykonywała to samo zadanie. Nie wiem, jak to się zachowuje przy sztucznej inteligencji, ale w wielu wypadkach jest to szybsze. A wszystko dzięki temu, że nie musisz obliczać tej samej wartości często wielokrotnie. Taki przykład:

function test(a:integer): integer;
begin
if a>0 then begin
result:=jakas_skomplikowana_funkcja(a);
result:=test(result);
result:=inna_skomplikowana_funkcja(a, result);
end
else result:=a;
end;

No i teraz to samo w wersji iteracyjnej robi się skomplikowane (zakładając, że jakas_skomplikowana_funkcja i inna_skomplikowana_funkcja są czasochłonne), gdyż tą pierwszą funkcję wykonywać będzie trzeba dwukrotnie więcej razy, niż w przypadku wersji rekurencyjnej. Oczywiście alternatywą byłoby tworzenie x zmiennych pomocniczych, gdzie x jest ilością powtórzeń pętli iteracyjnej. Ale to rozwiązanie mija się z ideą iteracji. I w praktyce absolutnie niczym nie bedzie się różnić od zoptymalizowanej wersji binarnej wersji rekurencyjnej.

0
Joseph Louis Lagrange napisał(a)
<font size="2"> > ##### wasiu napisał(a) > jesli dostalo sie program do przejecia i rozwiania?

Możesz to napisać po polsku? Rozumiem, ze miałeś na myśli: jeżeli przejęło się cudzy projekt jakiegoś programu w celu usunięcia błędów i analizy składni.

Dokladnie o to chodzi. Usuwanie bledow w programie rowna sie analizie skladni, fragmentu kodu, ktory sprawia problemy lub trzeba go rozwinac.

Joseph Louis Lagrange napisał(a)
<font size="2"> > ##### wasiu napisał(a) > bez zadnej dokumentacji czy opisow, dziesiatki funkcji, ktorych dzialanie jest niejasne i wiadome jest ze program zawiera duza ilosc bug'ow to tutaj mozna pokusic sie o przepisanie.

Przecież to jakaś paranoja! Jeżeli wiadomym jest, że program nie ma dokumentacji, funkcje w nim użyte są trudne w analizie i napisany jest z błędami to chcąc świadomie go przepisywać pamiętaj, ze świadomie również przepisujesz i błędy i funkcje bez zrozumienia ich działania a w konsekwencji uniemożliwiasz napisanie sobie dokumentacji do tego programu (w szczególności dokumentacji tych dziesiątków funkcji). Jeżeli chce się program (i zawarte w nim funkcje) zrozumieć (z znaczeniu zrozumieć ich algorytmy działania) to TRZEBA zanalizować KAŻDĄ funkcję i KAŻDĄ linijkę programu! Tylko w ten sposób zrozumiesz program i będziesz mógł napisać do niego dokumentację.

Chyba nie zrozumielismy sie co do pojecia przepisanie. Chodzi o to ze majac jakis program w 'tragicznym stanie' nie bawie sie w analizowanie kodu, czy kopiowanie funkcji do nowej wersji. Tylko siadam sobie na spokojnie, przygotowuje rozne diagramy jak widze dzialanie aplikacji wg wlasnego pomyslu, by uzyskac podobna albo wieksza funkcjonalnosc, robie architecture review z zespolem (bo moze ktos ma lepszy pomysl na rozwiazanie jakiegos problemu) i zaczynam(y) pisac (w zaleznosci od zasobow do danego projektu). Piszac wszystko od zera i dokumentujac kazda rzecz, osiagniemy zdecydowanie lepszy efekt koncowy.

Joseph Louis Lagrange napisał(a)

<font size="2">Ja sam osobiście jeżeli muszę zastosować jakąś pętlę i potrzebna mi jest zmienna to nazywam je zwykle a, b, c lub i (najczęściej bo pochodzi od słowa indeksować). Nie ma sensu nazywać przecież takiej zmiennej np. zmiennaZliczajacaPowtorzeniaWPetli

To chyba oczywiste? Chodzi mi bardziej o przypadek typu: funckja bierze 5 parametrow, a parametry nazywaja sie "a,b,c,d,e" .... jak dostaje taki kod do poprawiania to mnie krew zalewa...

Joseph Louis Lagrange napisał(a)
<font size="2"> > ##### wasiu napisał(a) > Minusy sa oczywiste: prawdopodobnie mozemy popelnic te same bledy, jak i nienadaje sie to zupelnie do wiekszych projektow.

Co do pierwszej części się zgodzę. Przepisywanie żywcem funkcji z błędami to minus. Ale co do drugiej już nie. Przepisywanie tego rodzaju programów nie nadaje się nie tylko do dużych projektów. Takie postępowanie nie nadaje się do WSZYSTKICH projektów. Argumenty patrz wyżej.

Z calym szacunkiem... ale mowilem odnosnie projektow, ktore po zajrzeniu w nie sa naprawde tandeta robiona w pospiechu by zdazyc na termin. Idac za Pana wnioskowaniem mozna by zalozyc ze z rozpadajacego sie malucha moznaby wyklepac Mercedesa... ale czy naprawde on nim bedzie i czy naprawde to nam zajmie mniej czasu niz budowa od nowa?

W takim przypadku zycze powodzenia w analizowaniu aplikacji, ktora dziala na kilku watkach jednoczesnie, komunikujacymi sie miedzy soba. Z reguly napisanie tego od nowa, zajmie mniej czasu niz analizowanie czasami bezsensownych rozwiazan jakie ktos sobie wymyslil. A niestety, ladny styl programowania to jest cos co niewiele osob wynosi ze studiow. Kody, ktore najbardziej kocham to takie pisane zupelnie bez wciec, o programowaniu obiektowym zapomnij, a o dokumentacji czy sensownym nazywaniu roznych zmienna tym bardziej... i pomyslec ze za to niektorzy dostaja pare tysiecy miesiecznie...
Sam wymog dokumentowania nie podoba sie czesci osob w moim zespole i o ile ludzie nie sa sprawdzani to robia to na odwal, a to chyba jedna z najwazniejszych rzeczy przy dalszym rozwijaniu czegos. Ze stosowaniem camelowskiej notacji tak samo. Niestety, duzo programistow jest niechlujna i nieprzygotowana do takich rzeczy jak dokumentacja kodu. Owszem, na studiach slyszeli o tym i tylko tyle. A wystarczyly by chociazby naglowki opisac np w doxygenie dla kazdej funkcji...

</span></span></span></span>

0
<font size="2"> > ##### wasiu napisał(a) > Idac za Pana wnioskowaniem mozna by zalozyc ze z rozpadajacego sie malucha moznaby wyklepac Mercedesa... ale czy naprawde on nim bedzie i czy naprawde to nam zajmie mniej czasu niz budowa od nowa?

Tak! Oczywiście! Ale na początek coś innego.
Odnoszę wrażenie, że Pańskie kontrargumenty na moje wypowiedzi pisane są z lekką ironią i złośliwością. Kiedy coś napiszę Pan zaraz powołuje się na argument, że ?program jest tandetny?. Czy ja napisałem, że powinno się analizować programy ?tandetne?? Nie! Tak nie napisałem. Aczkolwiek w każdym projekcie (większym czy mniejszym) zdarzają się błędy. Jednakże nie są to błędy, które uniemożliwiają prawidłowe funkcjonowanie programu. Tak jak są chochliki drukarskie można by te błędy nazwać chochlikami algorytmicznymi. Wszak program daje się skompilować jak również podaje prawidłowe wyniki. Żaden programista nie napisze od razu maksymalnie zoptymalizowanego i najlepszego jakościowo programu. Zawsze da się coś poprawić. Pętlę zamienić na inną, argument przesłać przez wskaźnik czy też przebudować klasę.
Swój post napisałem w oparciu o post pana Adama, który napisał:

Oleksy_Adam napisał(a)

Program działa ok.

A więc program DZIAŁAŁ i zwracał PRAWIDŁOWE WYNIKI. Moje wszelkie spostrzeżenia tyczyły się właśnie takiego programu, który działa, zwraca prawidłowe wyniki, a jedyne czego wymaga to poprawienia klas czyli mówiąc ogólnie poprawienia przejrzystości i jakości algorytmów.
A Pan kontrargumentuje to, rzekłbym w infantylny sposób ale nie chciałbym nikogo urazić. Ale ciągle Pan pisze jakoby program był beznadziejny, użył Pan słowa ?tandetny?.
Chwileczkę? ale jeżeli program jest tandetny (a ja przez to rozumiem, że uruchomia się co drugie włączenie albo zawiesza system po 5 min.) a ja wiem, że jest, to W OGÓLE go nie przepisuję (obojętnie czy są to małe funkcję czy większe pakiety). Mało tego. Nawet nie poprawiłbym składni! Po prostu napisałbym zupełnie NOWY program. Poprawianie programu ?tandetnego? się mija z celem. Program pana Adama nie był ?tandetny? jedynie wymagał przeróbki.

A teraz wracając do malucha i mercedesa. No jasne, że się da. Nie takie rzeczy ludzie robią na świecie. Ale jak już napisałem wyżej w tym poście, dla mnie (podkreślam DLA MNIE) lepiej napisać od nowa program niż poprawiać co drugą linijkę w ?tandetnym? projekcie.

A na zakończenie dodam jeszcze że jeżeli chce się opatrzyć swój program napisem ?v. 2.0? to nie można go napisać od początku. Bo jak już wcześniej napisałem nie będzie to wersja 2.0 starego programu ale będzie to wersja 1.0 całkiem nowego programu. Może się zdarzyć, że interfejs użytkownika będzie identyczny, może się zdarzyć, że napisze się te same funkcje o tych samych nawet nazwach, może się nawet zdarzyć, że nowy algorytm będzie zgodny w 95%, to jednak nie jest już wersja 2.0 lecz 1.0 nowego programu. Jeżeli chce się zrobić wersje 2.0 swojego programu to trzeba niestety poprawić swój program. Przecież nie można mieć pewności, że jednak czegoś co wygląda już na maksymalnie zoptymalizowane się nie poprawi.

I jeszcze jedno: Usuwanie błędów w programie to nie to samo co analiza składni. Zarówno w jedną jak i w drugą stronę.

Resztę postu pozostawiam bez komentarza</span>

0

Podam na przykładzie:
Stara wersja:

procedure TDaySheet.xsgArkuszCellProps(Sender: TObject; Canvas: TCanvas;
  var Alignment: TAlignment; var CellText: String; AState: TGridDrawState;
  Row, Col: Integer);
var
 i :Integer;
 s :string[2];
begin
 s := AnsiUpperCase(CellText);
 if (s = 'O') or (s = 'OK') then
    begin
     CellText := 'OK';
     Canvas.Font.Color := clBlue;
     Canvas.Brush.Color := clYellow;
    end else
    if (s = 'N') or (s = 'NG') then
        begin
         CellText := 'NG';
         Canvas.Brush.Color := clLightSilver;
         Canvas.Font.Color := clRed;
         Canvas.Font.Style := [fsBold, fsItalic];
        end;

 AllParts := 0;
 PartOk := 0;
 PartScrap := 0;
 for i := 1 to xsgArkusz.RowCount-1 do
  begin
   s := AnsiUpperCase(xsgArkusz.Cells[2, i]);
   if (s = 'O') or
      (s = 'OK') or
      (s = 'N') or
      (s = 'NG') then Inc(AllParts);
  end;

 xsgResult.Cells[0,1] := IntToStr(AllParts);
 for i := 1 to xsgArkusz.RowCount-1 do
  begin
   s := AnsiUpperCase(xsgArkusz.Cells[2, i]);
   if (s = 'O') or (s = 'OK') then Inc(PartOk);
   if (s = 'N') or (s = 'NG') then Inc(PartScrap);
  end;
 xsgResult.Cells[1,1] := IntToStr(PartScrap);
 xsgResult.Cells[2,1] := IntToStr(PartOK);
end; // xsgArkuszCellProps

Nowa wersja:

procedure TDaySheet.xsgArkuszCellProps(Sender: TObject; Canvas: TCanvas;
  var Alignment: TAlignment; var CellText: String; AState: TGridDrawState;
  Row, Col: Integer);
var
 i :Integer;
 s :string[2];
begin
 s := AnsiUpperCase(CellText);
 if (s = 'O') or (s = 'OK') then
    begin
     CellText := 'OK';
     Canvas.Font.Color := clGreen;
     Canvas.Brush.Color := clMoneyGreen;
    end else
 if (s = 'N') or (s = 'NG') then
     begin
      CellText := 'NG';
      Canvas.Brush.Color := clRed;
      Canvas.Font.Color := clYellow;
      Canvas.Font.Style := [fsBold, fsItalic];
      end;

 FillChar(Wyniki, SizeOf(TWyniki), 0);

 for i := 1 to xsgArkusz.RowCount-1 do
  begin
   s := AnsiUpperCase(xsgArkusz.Cells[2, i]);
   if (s = 'O') or (s = 'OK') then Inc(Wyniki.OK);
   if (s = 'N') or (s = 'NG') then Inc(Wyniki.NG);
  end;
  Wyniki.ALL := Wyniki.OK + Wyniki.NG;

  ledZwulk.Text   := IntToStr(Wyniki.ALL);
  ledDobre.Text   := IntToStr(Wyniki.OK);
  ledWadliwe.Text := IntToStr(Wyniki.NG);
end; // xsgArkuszCellProps

Poprawa czytelności, usunięcię zbednej petli. Nazwijmy to tuning.

0

Ale wciąż brak komentarzy i określenia co się czym zajmuje - dalej jest to kiepski kod w tej kwestii.

//Added:
No to trochę lepiej, ale mimo wszystko zaglądając do takiej funkcji nieskomentowanej (akurat te są w miarę proste, ale często są bardziej skomplikowane funkcje), można mieć problemy z jej zrozumieniem. Komentarze wewnątrz funkcji są również bardzo istotne (chyba, że z góry zakładasz, że jej nie będziesz już nigdy pod maskę zaglądał, ale rzadko się takie założenia sprawdzają).

0

Opisy funkcji mam w nagłówkach klas.

0
Joseph Louis Lagrange napisał(a)

... jeżeli program jest tandetny (a ja przez to rozumiem, że uruchomia się co drugie włączenie albo zawiesza system po 5 min.) a ja wiem, że jest, to W OGÓLE go nie przepisuję (obojętnie czy są to małe funkcję czy większe pakiety). Mało tego. Nawet nie poprawiłbym składni! Po prostu napisałbym zupełnie NOWY program. Poprawianie programu ?tandetnego? się mija z celem. Program pana Adama nie był ?tandetny? jedynie wymagał przeróbki...

Z gory przepraszam, jezeli poczul sie Pan urazony moim poprzednim postem. Fakt, moze za bardzo odbieglem od tematu postu i skupilem sie bardziej na 'tandetnym' programie z ktorym sam mialem stycznosc. Co do Panskiego postu i fragmentu zacytowanego powyzej to w pelni sie zgadzam i w sumie taki tok myslenia przedstawialem od poczatku, jako wskazowke dla pana Adama. Wkoncu nie wiemy jak jego program dziala, a rozni ludzie, roznie okreslaja ten stan.

0

Ja bym postarał się zaprojektować architekturę na nowo, w oparciu o sprawdzone wzorce projektowe, a następnie zassał ile tylko się da implementacji ze starego projektu. Bo chyba nigdy nie jest tak, że wszystko jest skwaszone. No chyba, że chcesz to napisać w innym języku, to i tak będziesz musiał na nowo zakodować.

Mam teraz bardzo podobny problem, bo modernizuję system, który działa, ale jest napisany miejscami bardzo toporie i nie ma np. w ogóle testów. Ba, jest nietestowalny, bo wszystko zależy od wszystkiego. Implementacja wielu modułów zostanie, bo działają sprawnie, natomiast zostaną pocięte niektóre zależności międzymodułowe, tak by każdy moduł dało się testować osobno. Takie rzeczy jak EJB 3.0 czy Spring niesamowicie ułatwiają zadanie. Po takim refactoringu można dopisać testy, a jak coś będzie wyjątkowo źle działało, to wtedy pisze się od nowa. Szkoda tracić czas na pisanie od nowa 200 tys. linii, które mimo wszystko w 99% działają dobrze.

1 użytkowników online, w tym zalogowanych: 0, gości: 1