Używamy cookies

Od 22 marca obowiązuje nowe prawo telekomunikacyjne nakazujące informować użytkowników telekomunikacyjnego urządzeniu końcowego abonenta (to to za bełkot? nie można było napisać przeglądarki?) o zapisywaniu lub odczytywaniu informacji na tym urządzeniu, a także o celu w jakim się to robi.

Informuję zatem, że używamy cookies w następującym celu: żeby wszystko działało.

Pójdę nawet dalej, informując o celu tego nowego prawa: otóż dzięki niemu banda niepotrzebnych nikomu urzędników z Ministerstwa Administracji i Cyfryzacji:

  • udowodniła przełożonym, że jednak są potrzebni
  • udowodniła, że zależy im na bezpieczeństwie obywateli
  • wykazała się inicjatywą zasługującą na premię
  • ograniczyła bezrobocie w sektorze IT
  • ma poczucie dobrze spełnionego obowiązku

Czyż to nie cudowne, jak waadza o nas dba?

Hoisting w JavaScript

Na początek zagadka: jakie komunikaty wyświetli poniższy kod?

Odpowiedź brzmi, oczywiście: undefined!

wat

W przeciwieństwie do jezyków takich jak C czy C#, nie każdy blok kodu definiuje zakres zmiennej, a jedynie funkcja. Nie ma przy tym znaczenia, w którym miejscu funkcji zmienną zadeklarujemy – będzie ona dostępna w całej funkcji, także przed deklaracją. Dlatego alert(x) nie zobaczy zmiennej globalnej, tylko lokalną. I zobaczy undefined dlatego, że co prawda zmienna jest już zdefiniowana, ale przypisanie do niej wartości ma miejsce później.

Powyższy kod będzie więc równoważny z takim:

A zatem – można powiezieć, że deklaracje zmiennych są jakby “wyciągane” (ang hoisted) na początek funkcji.

Ot, jedno z wielu dziwactw JavaScriptu.

Jaki z tego morał? Dobrą praktyką jest deklarowanie wszystkich zmiennych w jednej instrukcji var na samym początku funkcji. Taką też regułę posiada JSLint (i jego fork, JSHint), narzędzie sprawdzające styl kodu, którego używać powinien każdy programista JS.

Co się zmienia, co się nie zmienia

Jak rozplanować poszczególne części systemu, klasy, moduły, komponenty? Mnóstwo można by tu napisać, ale dziś tylko jedna zasad: oddzielaj to co się zmienia od tego, co się nie zmienia.

Każda nietrywialna aplikacja będzie się zmieniać. Będą zmieniać się wymagania, bo zmienia się wizja albo sytuacja klienta. Jak więc poukładać klocki tak, żeby zmiana wymagań nie wiązała sie z rozsypaniem całej budowli?

Zidentyfikować zawczasu, jaka część funkcjonalności będzie podatna na zmiany i oddelegować ją do osobnej klasy. Z projektu wyłonią się 3 obszary:

  1. Niezmiene serce systemu. Ten kod może się nie zmieniać całymi latami. Można raz napisać testy i one cały czas będą przechdzić, bo nic się nie zmienia.
  2. Polityki, używając terminologii DDD. Ten kod będzie sie zmieniał często. Klient wymyślił nowy sposób naliczania rabatu? Super, napiszmy nową klasę RebatePolicy, przetestujmy ją, a starą wyrzućmy. Wszystko inne działa, jak działało.
  3. Plumbing code. Niezbyt fascynujący kod, którego zadaniem jest sklejanie (1) i (2) w działający system.

Łatwo powiedzieć, trudniej zrobić. Cała sztuka w umiejętności zgadnięcia, co może się zmieniać i ukryciu tego pod niezmiennym interfejsem. Odwołując się do wspomnianego RebatePolicy – co metody tej klasy powinny mieć na wejściu? Cenę, cały produkt, historię użytkownika, jakiś kod rabatowy? A na wyjściu? Nową cenę, kwotę rabatu, procent? Nie wystarczy nam wiedzieć, że algorytm rabatu będzie się zmieniał. Trzeba jeszcze tak zaprojektować moduł, żeby zmiana logiki nie wymuszała zmiany API. Cóż nam po wydzieleniu rabatów do osobnej klasy, jeżeli jej zmiana będzie wymagała zmian także w klasach, które jej używają? Tych, które miały być niezmienne!

Polityki mogą się zmieniać, ale ich interfejsy powinny być stabilne.

Człowiek po to jest stworzony, aby Boga, Pana naszego, chwalił, czcił i Jemu służył, a przez to zbawił duszę swoją.

Inne zaś rzeczy na obliczu ziemi są stworzone dla człowieka i aby mu pomagały do osiągnięcia celu, dla którego on jest stworzony.

Z tego wynika, że człowiek ma korzystać z nich w całej tej mierze, w jakiej mu one pomagają do jego celu, a znów w całej tej mierze winien się od nich uwalniać, w jakiej mu są przeszkodą do tegoż celu.

I dlatego trzeba nam stać się ludźmi obojętnymi nie robiącymi różnicy w stosunku do wszystkich rzeczy stworzonych, w tym wszystkim, co podlega wolności naszej wolnej woli, a nie jest jej zakazane lub nakazane, tak byśmy z naszej strony nie pragnęli więcej zdrowia niż choroby, bogactwa więcej niż ubóstwa, zaszczytów więcej niż wzgardy, życia długiego więcej niż krótkiego, i podobnie we wszystkich innych rzeczach.

Natomiast trzeba pragnąć i wybierać jedynie to, co nam więcej pomaga do celu, dla którego jesteśmy stworzeni.

ĆD, 23