Skip to content


Single Responsibility Principle

Wczoraj mówiliśmy o tym, że funkcja powinna wykonywać jedną rzecz. Świetnym papierkiem lakmusowym jest nazwa funkcji. Jeśli można łatwo nadać jej nazwę i nie zawiera spójników typu i, lub, albo, oraz (lub ich odpowiedników w j. angielskim Uśmiech ) to jesteśmy na dobrej drodze. Funkcje, które wykonują kilka czynności są wprowadzają po prostu w błąd.

A co z klasami?

Single Responsibility Principle mówi, że klasa powinna mieć jedną odpowiedzialność, powinna mieć jeden powód do zmiany. Takie podejście powoduje, że powstaje bardzo dużo za to bardzo małych klas. Małe klasy łatwiej się czyta i łatwiej się je “ogarnia” to nie podlega dyskusji. Co więcej nie budujemy potężnych klas posiadających setki czy nawet tysiące (o zgrozo) linii kodu.

Popatrzmy na taki kawałek kodu

    public class Employee
    {
        private string Name;
        private string Surname;
        private string SomeOtherData;
        private string AboutThisEmployee;

        private string fileName;

        //...
        //...
        //...

        public void SetFileName()
        {
            // zapytaj użytkownika o nazwę pliku
            fileName = fileNameGivenByTheUser();
        }

        public void Save()
        {
            var stream = new XmlStream(fileName);
            //..
            //    ..
            //       ..
        }

        public void SerializeToFile(string xmlFileName)
        {
            fileName = xmlFileName;
            var xml = new XDocument();

            var xmlStream = new XmlTextWriter(fileName, Encoding.UTF8);
            xml.Save(xmlStream);
        }

    }

Kod taki jak powyżej powstaje nieintencjonalnie. Powstaje ponieważ klasy robią wiele rzeczy i wielokrotnie wykorzystujemy te same zmienne do różnych rzeczy. Problem w powyższym przypadku jest taki, że wywołując metodę SetFileName  a potem Save i ponownie Zapis kod zachowa się tak jak przewidujemy, jednak jeśli w między czasie ktoś skorzysta z metody SerializeToFile to zmieni się zmienna fileName i kolejne wywołanie metody Save zapisze już do innego miejsca niż do tego, które ustawiliśmy w metodzie SetFileName.

Jest jeszcze jeden problem.

Takie pisanie klas powoduje, że często dodając nowy sposób zapisu po prostu dodajemy nową metodę: SerializeToDocx, SerializeToOdt, SerializeToCloud SerializeToWhethever. Dopisujemy kolejne metody a tymczasem klasa puchnie. Przy osiągnięciu masy krytycznej, wprowadzenie jakiejkolwiek zmiany, nawet tej najmniejszej powoduje, że spędzamy godziny na debugowaniu kodu i sprawdzaniu dlaczego nie zawsze działa tak jak byśmy tego chcieli.

Rozwiązaniem jest Single Responsibility Principle – pojedyncza odpowiedzialność. Klasa posiada jedną odpowiedzialność. W powyższym przykładzie aż prosi się aby powstała klasa Pracownik i dwie klasy do zapisu. Jeśli pracownik zamiast wiązać się z konkretną klasą do zapisu, wykorzystywał będzie jedynie interfejs (IZapisz) i metodę zapisz z tego interfejsu, to wówczas będziemy mogli dowolnie dodawać kolejne klasy do zapisywania i wymiennie je stosować. Co więcej dodanie nowego sposobu zapisu czy też zmodyfikowanie istniejącego nie będzie wymagało nawet otwierania klasy Employee. Możemy taką pracę delegować na kogoś innego.

Single Responsibility Principle (SRP) uważam za jedną z nabardziej znaczących dlatego jutro dalej, będziemy wałkować ten temat.

Posted in podstawy programowania, programowanie.

Tagged with , , , , , , .


Lekcja języka polskiego w programowaniu

Wielu programistów to umysły tzw. ścisłe. Osoby takie mają to do siebie, że nie pałają wielką radością do przedmiotów typu język polski – muszę kupić ziemniaki – czy też historia. Mimo pewnej niechęci i braku opanowania sztuki pięknego pisania wypracowań, większość z nich (nas) – a do tych ziemniaków jeszcze jakieś pomidory – potrafi przestrzegać pewnych zasad pisząc owe wypracowania. Od małego uczą nas, że wypracowanie powinno mieć wstęp, rozwinięcie – no i nie mogę zapomnieć o mięsie na obiad – no  i oczywiście zakończenie. Czy ktoś  wrzucił by w kolejne zdania wypracowania np. listę zakupów?

No właśnie…. pisząc wypracowanie, zamieszczamy tam tylko treść owego wypracowania – mniej lub bardziej zgrabnie ale tylko treść.

ile to razy napisałem kod tego typu:

public FileStream UtworzPlik(string sciezka,string nazwaPliku){
  if( ! Directory.Exist(sciezka) ){
    Directory.Create(sciezka)
  }
  var plik = File.Create(Path.Combine(sciezka,nazwaPliku));
  return plik;
}

popatrzmy co tutaj jest nie tak. Funkcja nazywa się UtworzPlik ale w środku tworzymy katalog. Coś jest nie tak. Jeżeli funkcja tworzy plik to dlaczego tworzy też katalog? Taka wydawało by się pierdołka powoduje, że jeżeli będziemy chcieli wykorzystać ten kod w późniejszym czasie w innym miejscu po prostu wywołując go dostaniemy i plik i katalog.

Oczywiście sprytny programista sobie z tym poradzi:

public FileStream UtworzPlik(string sciezka,string nazwaPliku, bool utworzKatalog){
  if( ! Directory.Exist(sciezka) && utworzKatalog){
    Directory.Create(sciezka)
  }
  var plik = File.Create(Path.Combine(sciezka,nazwaPliku));
  return plik;
 }

Oto pierwszy krok do złego kodu, a należy pamiętać, że zły kod boli całe życie. Wykonanie takiego fantastycznego „hacku” kilka razy na tej funkcji może doprowadzić do sytuacji gdy wywołanie funkcji będzie wyglądało tak:

UtworzPlik(@"c:\temp\moje\testowe",@"plikTymczasowy.txt",true,false,3,false,false);

i teraz konia z rzędem temu kto zgadnie co może robić powyższa funkcja bez zaglądania do niej. Przeglądnij swój kod bo jest duża szansa, że takie cuda piszesz. Ja przyłożyłem rękę do kilku (nastu) takich funkcji. Nie róbmy tego więcej.

Posted in podstawy programowania, programowanie.

Tagged with .


Podstawy programowania

Niniejszy post jest 200-tną notatką na blogu. Aż dziw bierze, że tak długo już prowadzę tego bloga (pierwszy wpis 26.01.2008). Wprawdzie 200 wpisów  na 4 lata to niewiele, to nie sądziłem, że tak długo będę to robić. Co bardziej ciekawscy pewnie i znajdą moje pierwsze podejście do blogowania z pierwszym wpisem z 7/14/2005 09:09:00 AM (wtedy nawet Visty nie było na świecie). Linka nie zamieszczam bo wiele z tamtego nie wyszło ;-) .

Tak zacna i okrągła okazja zostaje niniejszym wykorzystana jako pierwszy z cyklu postów o podstawach programowania. Jednak nie mam zamiaru opisywać poszczególnych konstrukcji językowych ani też kolejnych bibliotek, nie będę również mówił o efektywnych algorytmach. Pisał będę o tym jak pisać aplikacje aby można było je długo i efektywnie rozwijać. Przejdę po zasadach SOLID (ale nie tylko tych 5 podstawowych), przejdę po TDD oraz kilku innych aspektach, które dadzą Ci szansę uniknąć błędów jakie doprowadziły niejedną firmę na skraj bankructwa.

Natchnieniem do napisania tej serii jest fakt, że na żadnej z trzech uczelni na jakich miałem przyjemność studiować nie usłyszałem słowa o tym o czym będę pisał. Usłyszałem natomiast o wskaźnikach, strukturach i zajebistości pięknie dziedziczenia. Nikt niestety nie mówił jak pisać programy.

W czym problem? Przecież każdy średnio rozgarnięty student potrafi pisać programy. Ci co bardziej rozgarnięci znają kilka języków, bibliotek, frameworków etc. Co więcej pracują i dostają za swoją pracę pieniądze.

Problem polega na tym, że piszą kod, który powoli ich przerasta. Z każdą dodaną linią staje się trudniejszy i bardziej zagmatwany.

“…ale przecież programowanie to trudna sztuka, było trudno napisać, musi być trudno zrozumieć”

nic bardziej mylnego. Problemy jakie rozwiązuje informatyka są wystarczająco złożone aby je jeszcze niepotrzebnie komplikować. Każdy problem jaki rozwiązujemy powinien odzwierciedlać złożoność esencjonalną czyli tą która jest istotą rozwiązywanego problemu ale nie powinien wnosić dodatkowej złożoności przypadkowej generowanej przez… uwaga, uwaga…

PROGRAMISTÓW

Spójrzmy na poniższy wykres.

image

Przedstawia on produktywność w czasie. Lewa strona to początek projektu. To ten piękny czas kiedy wybieramy File->New Project albo tworzymy nowe repozytorium lub zakładamy nowy katalog na dysku lub cokolwiek innego (bez względu na język programowania, platformę etc.). Od tego momentu zaczyna się życie naszego projektu. Pierwszą funkcjonalność zazwyczaj możemy napisać w kilka minut lub godzin, następną również, i następną i następną i….. niestety to nie rozwija się tak w nieskończoność. Po tygodniu lub miesiącu prace idą trochę wolniej. Nadal bardzo szybko ale już odrobinę wolniej. Kolejny miesiąc to kolejne spowolnienie…. itd. Z tygodnia na tydzień i miesiąca na miesiąc wprowadzanie kolejnych funkcjonalności staje się coraz trudniejsze. Ilość założeń, klas, zmiennych, funkcji, wymagań narasta do takiej ilości, że dodanie czegoś nowego staje się pracą na ugorze.

Dlaczego tak się dzieje? Bo przyszły skrzaty i zamieszały w kodzie? Bo inni członkowie zespołu to idioci nieuki. Bo klienci to idioci mają nierozsądne wymagania?

NIE !!! Bo tak to napisałem

Wracając do wykresu, na szczęście wykres nie spada do zera. Zawsze jesteśmy w stanie wprowadzić jakieś zmiany. Niestety w pewnym momencie koszt wprowadzania zmian jest tak duży, że zapada kosztowna (dla zarządu) a zarazem radosna (dla programistów) decyzja – zaczynamy nowy projekt. Wracamy do punktu wyjścia i……. ci sami idioci wspaniali programiści, którzy doprowadzili projekt nad krawędź zaczynają zabawę od początku. Niestety sporo firm nie jest wstanie wytrzymać takiej huśtawki i upada (przy ogólnej radości i aplauzie zarządu, programistów a przede wszystkim klientów)*.

Celem niniejszego cyklu jest obnażenie mechanizmów mogących prowadzić do powyższej sytuacji oraz pokazanie mechanizmów pozwalających zapobiegać temu.

 

*) sarkazm

Posted in podstawy programowania, programowanie.

Tagged with , .


Warsztat czyli moje narzędzia pracy–te używane sporadycznie

W zeszły czwartek opublikowałem post pod tytułem “Warsztat czyli moje narzędzia pracy”. Opisałem narzędzia, które są dla mnie obecnie najbardziej przydatne. Jednak nie są to wszystkie narzędzia dlatego poniżej zamieszczam listę sporadycznie używanych ale takich, które spełniają swoją role i mogą się przydać również Tobie:

Notepad2

jak dla mnie perfekcyjny zamiennik notatnika systemowego. Ma numerowanie linii i kolorowanie składni (dodatkowo czas używam również jako narzędzia do konwersji pomiędzy różnymi kodowaniami). Żadnych zakładek czy innych ulepszaczy. Prosty zgrabny notatnik na sterydach. http://www.flos-freeware.ch/notepad2.html

NCover

NCover to potężne narzędzie do code coverage. Potrafi współpracować z wieloma frameworkami do testowania, ma przyjemną nawigację i eksportuje raporty. Codziennie funkcję tą spełnia mój ulubiony NCrunch jednak co kilka dni prześwietlam kod NCoverem. http://www.ncover.com/

NDepend

Jest to chyba najrzadziej używane narzędzie z całego arsenału jednak możliwości jakie daje są niewyobrażalne. W olbrzymim skrócie NDepend prześwietla kod pod każdym możliwym kątem. Producent chwali się że mają 82 metryki – nie liczyłem ale jest ich od zatrzęsienie. Jeśli tego mało, można budować własne za pomocą SQL-o podobnych zapytań ala Select types from namespace “….” where IsUsingUnboxing or IsUsingBoxing (i mamy listę boxowań i unboxowań).  http://www.ndepend.com/

FinalBuilder

FinalBuilder to potężne narzędzie do automatyzacji. Począwszy od CI przez Build Server i Continious Delivery aż na automatyzacji wszystkiego co się nam przyśni kończąc. Używam praktycznie codziennie jednak narzędzie trafiło tutaj ponieważ jako część środowiska produkcyjnego po prostu wykonuje swoją pracę gdzieś w tle więc moja interakcja z nim jest sporadyczna. http://www.finalbuilder.com/

Idea IntelliJ

Prawdopodobnie najlepsze środowisko do programowania w Javie, Scali, Clojure i kilku innych językach. Jest wersja darmowa na której można poćwiczyć. Jeśli miałbym pisać zawodowo w Javie to tylko z tym cudem – znając ReSharpera bardzo łatwo zacząć wydajnie pracować – w końcu to ten sam producnet Uśmiech http://www.jetbrains.com/idea/

Windows Live Writer

W czymś trzeba pisać notatki na bloga, część powstaje w samym wordpress-ie a część właśnie w Windows Live Writerze – jest wszystko co potrzeba z korektą błędów na czele.

EverNote

Bardzo dobre narzędzie do przechowywania notatek, które zastąpiło mi OneNote-a. Materiały można wysyłać mailem, można pisać przez komórkę (sprawdzone na iPhonie i WP7, android pewnie też wspierany jest) no i oczywiście przez desktop – pełna integracja. U mnie EverNote pełni funkcję archiwum (z GTD).  http://www.evernote.com/

SkyDrive i Google Docs

Obie chmury używam w miarę zamiennie. Część rzeczy przechowuje w google-u część w microsofcie. Z jednej strony żeby znać obie usługi a z drugiej strony żeby wykorzystać najlepsze cechy obu. SkyDrive przechowuje zdjęcia ze względu na wygodny i ładny interfejs (picassa dla mnie jest bezużyteczna pod tym względem). Google Docs używam jeśli chcę popracować wspólnie z kimś przez internet.

Posted in Ciekawostki, Produktywność.

Tagged with , , , , , .


Uncle Bob pracuje nad kolejną książką

imageI should work on the script for E12. I should work on my book. I should work on my keynote. I should go to bed.

Źródło: http://twitter.com/#!/unclebobmartin/status/194225517883437056

Najwyraźniej Uncle Bob pracuje nad nową książką. Czekam zatem na pierwsze wydanie.

Posted in Ciekawostki.

Tagged with .