/ kwiatki_programowania

Kwiatki programowania

Brzydki kod każdy z nas widział ...

Języki programowania różnią się od siebie, mamy języki funkcyjne, obiektowe, mieszane, niskiego poziomy wysokiego itd. Jednak każdy z nas widział choć raz jakiś brzydki kawałek programu. W tym poście chciałbym pokazać parę przykładów z ostatnich miesięcy, na które udało mi się natrafić i pokażę jak można je poprawić ( oczywiście poprawiony kod da się napisać jeszcze lepiej)

Na pierwszy ogień kod napisany w js (angularjs)

W wielkim skrócie, poniższy fragment iteruje po obiekcie o strukturze drzewiastej. Gdy już dotrzemy do ostatniego dziecka, pobierana jest lista obiektów (agentów) (nazwy zmiennych są inne niż te użyte w projekcie) :

 for (var t = 0; t < tree.countries.length; t++) {
            var country = tree.countries[t];
            if (groupName && groupId && groupName == 'country' && country.countryId != groupId) {
                continue;
            }
            
            if(country.cities){
                for (var b = 0 ; b < country.cities.length; b++) {
                    var city = country.cities[b];
                    if (groupName && groupId && groupName == 'city' && city.cityId != groupId) {
                        continue;
                    }
                    for (var s = 0; s < city.streets.length; s++) {
                        var street = city.streets[s];
                        if (groupName && groupId && groupName == 'street' && street.streetId != groupId) {
                            continue;
                        }
                        for (var te = 0; te < street.locals.length; te++) {
                            var local = street.locals[te];
                            if (groupName && groupId && groupName == 'local' && local.localId != groupId) {
                                continue;
                            }
                            for (var a = 0; a < local.agents.length; a++) {
                                var agent = local.agents[a];
                                agent.fullName = (agent.firstName ? agent.firstName : '') + (agent.lastName ? (' ' + agent.lastName) : '');
                                agents.push(agent);
                            }
                        }
                    }
                } 
            }
        }

No dobra niektórzy powiedzą, że jak trzeba 'przelecieć' całą kolekcję to tego nie unikniemy, jednakże kiedy z frontu klikniemy na jakiegoś nadrzędnego noda to i tak następny zostanie wybrany zawsze pierwszy element czyli mniej więcej coś takiego:

agents=countries[i].cities[0].street[0].locals[0].agents

Już nawet nie wspomnę, ze powyższy algorytm (o ile dobrze nauczyli mnie na studiach) jest złożoności O(n5) a te brzydkie ify ... są tylko po to, że klikająć na któregoś noda z poziomu htmla, musimy wiedzieć który z nich został kliknięty. Ok złożoność już maleje ale i tak w pesymistycznym założeniu zostaje taka sama.

Jak się pozbyć powyższych sprawdzeń? A można tak:

     onCountrySelected(country) {
        //country.cities[0].streets[0].locals[0].agents;
        // activate code here
    }

    onCitySelected(city) {
        //city.streets[0].locals[0].agents;        
        // activate code here    
    }

    onStreetSelected(street) {
        //street.locals[0].agents;    
        // activate code here    
    }

    onLocalSelected(local) {
        //local.agents;        
        // activate code here
    }

Czytelność wzrasta, szybko można znaleźć błąd i zostaje dobre pole do dalszej refaktoryzacji.

Ostatecznie założenie w projekcie zostało zmienione i dopiero klikając na odpowiedni local zostaje pobrana z niego lista agentów.

Od czego zacząć naprawianie?

  1. Czytelność - chwilę mi zajęło bo zrozumieć jak działa ten kod
  2. Analiza działania algorytmu a przeznaczeniem w aplikacji
  3. Rozbicie kodu (prawie zawsze da się rozbić na mniejsze, atomowe części)

Frontendowcu Ciebie też dotyczą zasady pisania dobrego kodu!

Usłyszałem kiedyś zdanie "Jestem frontendowcem, odciąłem się od backendu, więc oni niech robią swoje a ja swoje". Dobrze dobrze, lecz nie zwalnia Cię to z wręcz obowiązku unikania algorytmów o złożoności O(n5), Twój kod ma działać nie tylko na wypasionych komputerach / laptopach, a także smartfonie czy innym tablecie, (a tam już odczujemy "szybkość działania")

Bycie frontendem

owcem, backend'owcem, programistą aplikacji mobilnych, wbudowanych, game developerem itd. nie zwalnia z obowiązku dbania o SWÓJ KOD!

pozycje literacki

  1. Czysty kod (Obowiązkowa pozycja dla każego programisty)
  2. The Pragmatic Programmer: From Journeyman to Master (chyba moja ulubiona pozycja, wydana w 1999 wyprzedza zagadnieniami Czysty Kod o prawie 11 lat a nie zyskała rozgłosu a szkoda)
  3. Code complete (ponad 1000 stron, niestety jeszcze jej nie ukończyłem :))