Czym jest złożoność ?

40
CZYM JEST ZŁOŻONOŚĆ? Identyfikacja i rozwiązywanie podstawowych problemów Ciprian Alexandru Pitis

Transcript of Czym jest złożoność ?

CZYM JEST ZŁOŻONOŚĆ?Identyfikacja i rozwiązywanie podstawowych problemów

Ciprian Alexandru Pitis

O mnie

GOG.comSenior Web Developer

Czym się zajmuję?Rozwijam i utrzymuję kod

W międzyczasie szukam złotego Graala designu aplikacji ;)

GOG.com

Historia Start w 2008 pod skrzydłami CD Projekt - zespół 10 osóbObecnie zatrudnionych jest ponad 70 osób

Obecna pozycja

#1 globalnej dystrybucji klasycznych gier na PC i Mac #2 globalnej dystrybucji gier indie na PC i Mac

Partnerzy 220+ twórców i wydawców gier

Klienci Ponad 2.7 miliona unikalnych wejść miesięcznie z całego świata

Gry Ponad 800 tytułów w kataloguPonad 39 milionów gier na kontach użytkowników

Agenda

1. Czym jest złożoność?

2. Dlaczego złożoność jest problematyczna?

3. Złożoność a design kodu

4. Złożoność poznawcza

5. Podsumowanie i wnioski

Czym jest złożoność?

CZYM JEST ZŁOŻONOŚĆ?

• Trudność w zrozumieniu, wykonaniu i zweryfikowaniu poprawności projektu.

• Im większa liczba możliwych interakcji w procesie, tym więcej rzeczy może pójść nie tak.

Dlaczego złożoność jest problematyczna?

CZŁOWIEK TO NIE MASZYNA

• Ludzki umysł nie może ogarnąć nieskończonej ilości informacji.

• Według badań, człowiek może myśleć o maksymalnie 4 rzeczach na raz.

• Zbyt dużo informacji na raz to ryzyko nieświadomej pomyłki.

Dlaczego złożoność jest problematyczna?

TOKSYCZNY WPŁYW NA PROJEKT

• Złożoność rodzi złożoność.

• Zamiast myśleć o istocie problemu i sposobie rozwiązania musimy myśleć o stanie obecnym i o tym jak zaadaptować się do nowych warunków.

Złożoność a design kodu

PODSTAWOWE METRYKI

Cyclomatic Complexity (CC)

Liczba linearnie niezależnych ścieżek, w kodzie z jednym punktem wyjścia równa jest liczbie punktów decyzyjnychNPath Complexity (NP) Liczba możliwych różnych przebiegów w kodzie

Afferent Coupling (CA) Liczba klas, które polegają na danej implementacji

Efferent Coupling (CE) Liczba klas, na których polega dana klasa

Stability (I) Wartość: CE / (CA + CE), określa ogólną stabilność,0 to całkowita stabilność, 1 to całkowita niestabilność

Złożoność a design kodu

function fizzBuzz($n)

{

$output = "";

if ($output % 3 == 0) {

$output .= "Fizz";

}

if ($output % 5 == 0) {

$output .= "Buzz";

}

return $output;

}

Złożoność a design kodu

REKOMENDOWANE LIMITY (wg PMD i phpMD)

• CC <= 10

• NPath <= 200

• Powyżej podanych metryk, kod przeważnie zaczyna robić się trudnydo zrefaktorowania i zrozumienia.

http://phpmd.org/rules/index.html#code-size-rules

Złożoność a design kodu

TESTY JEDNOSTKOWE

• Chronią przed niepożądanymi zmianami.

• Pozwalają na bardziej swobodną refaktoryzację.

Złożoność a design kodu

• Kod ma 100% code coverage, 100% path coverage.

• Jesteśmy kryci przed każdą pomyłką?

• .. niestety nie. Ale prawie.

$this->assertEquals(fizzBuzz(2) == "");

$this->assertEquals(fizzBuzz(9) == "Fizz");

$this->assertEquals(fizzBuzz(10) == "Buzz");

$this->assertEquals(fizzBuzz(30) == "FizzBuzz");

Złożoność a design kodu

ROZBIJANIE PROBLEMÓW:SEPARATION OF CONCERNS

• Nasze aplikacje rozwiązują jakiś (duży) problem, najczęściej biznesowy.

• Każdy problem można rozbić na więcej pod-problemów.

Złożoność a design kodu

OBSŁUŻENIE ŻĄDANIA HTTP KLIENTA

PRZESŁANIE OBIEKTUREQUEST DO KONTROLERAURUCHOMIENIE BUNDLI STWORZENIE OBIEKTU

REQUEST

WYBRANIE ROUTE’A NAPODSTAWIE ŚCIEŻKIŻĄDANIA HTTP

ODESŁANIE ODPOWIEDZI

WYTWORZENIE OBIEKTU TYPU RESPONSE

ODPYTANIE BAZY DANYCHO ŻĄDANE INFORMACJE

GENERACJA WIDOKUDLA UŻYTKOWNIKA

URUCHOMIENIE INNYCHŻĄDANYCH PROCESÓW

ZAPYTANIE DOBAZY DANYCH

GENERACJASZABLONÓW TWIG

ZAPYTANIEDO CACHE

OTRZYMANIE OBIEKTU TYPU RESPONSE

Złożoność a design kodu

OBSŁUŻENIE ŻĄDANIA HTTP KLIENTA

URUCHOMIENIE BUNDLI STWORZENIE OBIEKTUREQUEST

WYBRANIE ROUTE’A NAPODSTAWIE ŚCIEŻKIŻĄDANIA HTTP

PRZESŁANIE OBIEKTUREQUEST DO KONTROLERA

WYTWORZENIE OBIEKTU TYPU RESPONSE

ODPYTANIE BAZY DANYCHO ŻĄDANE INFORMACJE

GENERACJA WIDOKUDLA UŻYTKOWNIKA

URUCHOMIENIE INNYCHŻĄDANYCH PROCESÓW

ZAPYTANIE DOBAZY DANYCH

GENERACJASZABLONÓW TWIG

ZAPYTANIEDO CACHE

Złożoność a design kodu

OBSŁUŻENIE ŻĄDANIA HTTP KLIENTA

URUCHOMIENIE BUNDLI STWORZENIE OBIEKTUREQUEST

WYBRANIE ROUTE’A NAPODSTAWIE ŚCIEŻKIŻĄDANIA HTTP

PRZESŁANIE OBIEKTUREQUEST DO KONTROLERA

WYTWORZENIE OBIEKTU TYPU RESPONSE

URUCHOMIENIE INNYCHŻĄDANYCH PROCESÓW

GENERACJA WIDOKUDLA UŻYTKOWNIKA

GENERACJASZABLONÓW TWIG

ODPYTANIE BAZY DANYCHO ŻĄDANE INFORMACJE

ZAPYTANIE DOBAZY DANYCH

ZAPYTANIEDO CACHE

Złożoność a design kodu

OBSŁUŻENIE ŻĄDANIA HTTP KLIENTA

PRZESŁANIE OBIEKTUREQUEST DO KONTROLERAURUCHOMIENIE BUNDLI STWORZENIE OBIEKTU

REQUEST

WYBRANIE ROUTE’A NAPODSTAWIE ŚCIEŻKIŻĄDANIA HTTP

WYTWORZENIE OBIEKTU TYPU RESPONSE

URUCHOMIENIE INNYCHŻĄDANYCH PROCESÓW

GENERACJA WIDOKUDLA UŻYTKOWNIKA

GENERACJASZABLONÓW TWIG

ODPYTANIE BAZY DANYCHO ŻĄDANE INFORMACJE

ZAPYTANIE DOBAZY DANYCH

ZAPYTANIEDO CACHE

ODESŁANIE ODPOWIEDZI

OTRZYMANIE OBIEKTU TYPU RESPONSE

Złożoność a design kodu

DOBRE OBIEKTY TO MAŁE OBIEKTY

• Uniwersalna zasada: „preferuj gęstszą sieć mniejszych obiektów od rzadszej

sieci większych obiektów” - Nigel Thorne

• Single Responsibility Principle

• Design By Contract (Liskov Substitute Principle)

• Dependency Inversion Principle

• Interface Segregation Principle

• Tell, don’t ask

http://stackoverflow.com/questions/243274/best-practice-with-unit-testing-abstract-classes

Złożoność a design kodu

SINGLE RESPONSIBILITY PRINCIPLE

• Każdy obiekt powinien mieć jedną odpowiedzialność.

• “Odpowiedzialność to powód do modyfikacji” - Robert C. Martin

Złożoność a design kodu

class AppKernel { … }

class Controller { … }

class TwigEngine implements EngineInterface { … }

Złożoność a design kodu

DESIGN BY CONTRACT

• Wprowadzenie jasnego kontraktu umożliwia jawne przekazanie informacji.

• Te informacje to m.in to, czego dana klasa oczekuje, co i w jakim wypadku zwraca, a także wyjątki które może zwrócić i co one oznaczają.

• Brak typów wartościowych (int, string…) oraz zwracanych wartości w PHP niestety to utrudniają, ale annotacje PHPDoc (@param, @return, @throws) i dobre IDE pomagają w utrzymaniu dyscypliny.

Złożoność a design kodu

interface UserRepository {

public function findOne(UserId $userId);

}

class MysqlUserRepository {

private $connection;

public function __construct(Connection $connection) {

$this->connection = $connection;

}

public function findOne(UserId $userId) {

return $this->connection->query("SELECT * from users WHERE id = :uid", [$userId->value()]);

}

}

class InMemoryUserRepository { […] }

Złożoność a design kodu

DEPENDENCY INVERSION PRINCIPLE

• Nie powinno być „hierarchii klasowej”. Zamiast tego, wszystko powinno być zależne od abstrakcyjnych interfejsów.

• Abstrakcja nie powinna polegać na implementacji (to ma być złączone z poniższym).

• Implementacja powinna polegać na abstrakcji.

Złożoność a design kodu

class BlogController {

public function __construct(BlogPagesRepository $repository ) { … }

}

interface BlogPagesRepository { … }

class MysqlBlogPagesRepository implements BlogPagesRepository { … }

class MongoDbPagesRepository implements BlogPagesRepository { … }

Złożoność a design kodu

INTERFACE SEGREGATION PRINCIPLE

• Klient nie powinien zależeć od metod, którego nie potrzebuje.

• Ułatwia tworzenie implementacji do granularnych interfejsów.

Złożoność a design kodu

interface VisitorInterface {

public function getIP();

}

interface UserInterface {

public function getId();

}

class HttpUser implements VisitorInterface, UserInterface { … }

class Crawler implements VisitorInterface { … }

class CliUser implements UserInterface { … }

Złożoność a design kodu

TELL, DON’T ASK

• Mów obiektom co mają robić, nie pytaj ich o stan.

• Stawiaj warunki tam, gdzie są one zasadne dla danego problemu.

Złożoność a design kodu

// BasketController.php

if($customer->getCountOfItemsInBasket() < 3) {

$customer->addToBasket($item);

}

ŹLE (IMPLEMENTACJA KLASY CUSTOMER WYCIEKA DO KONTROLERA):

Złożoność a design kodu

//BasketController.php

$customer->addToBasket($item);

//Customer.php

public function addToBasket($item) {

if($this->getCountOfItemsInBasket() < 3) {

[…]

}

}

DOBRZE:

Złożoność a design kodu

KORZYŚCI ZE STOSOWANIA

• Odizolowanie problemów od siebie = Większa elastyczność

• Mniejsze problemy = Mniejsza złożoność

Złożoność a design kodu

SCOPE

• Każdy kod posiada jakiś scope, w którym ma zadeklarowane swoje wartości.

• Wszystkie dane w scopie powinny być mu jawnie przekazane poprzez parametry.

Złożoność a design kodu

PROBLEMY ZE SCOPE’EM

• Global variable: global $var;

• Mutability: setFoo($foo) - Dla obiektów które nie przenoszą danych

• Zależność od implementacji

Złożoność a design kodu

POMOCNE NARZĘDZIA

phpMD Na podstawie reguł alarmuje Nas, gdy dana klasa/metoda może okazać się problematyczna w utrzymaniu

PHP Code Sniffer Sprawdza zgodność z standardami PSR

PHP Code Analyzer Wykonuje analizę statyczną kodu, inferencję typów , wykrywa proste błędy

Solidne IDE Wspomaga pisanie i formatowanie kodu, minimalizuje ryzyko wystąpienia pomyłki mechanicznej ( syntax error, zły typ, zła klasa, zła metoda.. etc. )

Złożoność poznawcza kodu

ZŁOŻONOŚĆ KOGNITYWNA

• Jawność tego, co dzieje się w kodzie dla osoby czytającej

• Często pomijana (ze względu na swoją „nietechniczność”), ale jest nie mniej ważna od złożoności samego kodu

Złożoność poznawcza kodu

ODBIÓR JEST WSZYSTKIM

• Czytelność kodu (Coding Style)

• Język wykorzystywany w aplikacji

• Domain Driven Design, Ubiquitous Language - metodologia, która minimalizuje narzut w odbiorze

Podsumowanie i wnioski

WNIOSKI

• Zdanie sobie sprawę z tego, co dokładnie sprawia, że kod ciężej utrzymać to pół sukcesu.

• Pisanie łatwego kodu jest trudne - przepisanie trudnego kodu może byćjeszcze trudniejsze.

• Sprawdzone rozwiązania z zakresu projektowania aplikacji pomagają w ograniczeniu złożoności aplikacji do koniecznego minimum.

• Czytelność i nazewnictwo są tak samo ważne co sam kod.

Podsumowanie i wnioski

CO ZYSKUJE DEVELOPER I PRODUCT OWNER?

• Czas

• Elastyczność w adaptacji do nowych wymogów biznesowych

• Elastyczność w tworzeniu technicznych implementacji

• Podatność na zmiany, odporność na uszkodzenia produktu

PYTANIA?

SZUKAMY WEBDEVÓWWięcej informacji u mnie lub na stronie GOG.com/work

DZIĘKUJĘ ZA UWAGĘ…i zapraszam potem do dyskusji przy pizzy ;)