Kod częściej się czyta, niż pisze. Więc logiczne jest to, że warto skupić się na pisaniu kodu, który jest łatwo zrozumiały dla programisty.
Na czytelność kodu składa się kilka czynników, jak na przykład: odpowiednie nazewnictwo, liczba linijek kodu itp.
Innym ważnym czynnikiem jest złożoność kodu. Im bardziej kod jest złożony, tym trudniej się go czyta.
Jedną z metryk, która pozwala na zmierzenie złożoności kodu, jest: złożoność cyklomatyczna.
Złożoność cyklomatyczna
Informuje ona o liczbie ścieżek prowadzących w kodzie. Mierzy się ja w funkcji/metodzie.
Dzięki tej informacji wiesz nie tylko, jak bardzo złożona jest funkcja/metoda, ale także o minimalnej ilości testów potrzebnych do napisania, aby w pełni pokryć kod testami.
Minimalna wartość złożoności cyklomatycznej wynosi: 1.
Ile to za dużo?
Do jakiej wartości złożoności cyklomatycznej powinniśmy dążyć? Nie ma na to jasnej odpowiedzi, ale im mniejsza wartość, tym lepiej.
Autor książki: Zrównoważony kod. Dobre praktyki i heurystyki dla inżynierów oprogramowania — Mark Seemann proponuje, żeby maksymalna wartość wynosiła 7. Dlaczego akurat 7? Argumentuje to tym, że mózg człowieka dysponuje pamięcią krótko terminową. Jest ona ograniczona. Kiedy programista natrafia w metodzie na wiele instrukcji warunkowych lub/i pętli stara się "ogarnąć", jak działa ten kod. Im bardziej jest on złożony, tym trudniej go zrozumieć. Dlatego warto ograniczyć złożoność cyklomatyczną do stałej wartości i się tego konsekwentnie trzymać.
Jeśli złożoność cyklomatyczna wynosi więcej niż ustalona wartość powinieneś zrefaktorować kod, w wyniku czego ta wartość się zmniejszy.
Jak to policzyć?
Złożoność cyklomatyczną liczy się w prosty sposób: zaczynasz od wartości 1, licznik zwiększasz za każdym, gdy napotkasz w kodzie: instrukcje warunkowe i pętle.
Sam proces liczenia złożoności cyklomatycznej warto zautomatyzować, instalując na przykład jakąś bibliotekę do statycznej analizy kodu.
Stos głębi, który wyświetla elementy, w kolejności od początku do końca. Na przykład mając trzy elementy, które są takich samych rozmiarów, ten ostatni zostanie wyświetlony jako widoczny, a resztę przykryje.
Stos daje także możliwość na sposób wyświetlania elementów poprzez wyrównanie (ang.: alignment) oraz na ustawienie odstępów między elementami (ang.: spacing).
Wyrównanie
Jeśli chodzi o wyrównanie, użyj właściwości: alignment.
Przy czym, każdy stos przyjmuje własne wartości:
Dla VStack:
.leading — wyrówanie do lewej
.center — wyrównanie do środka (domyślna wartość)
.trailing — wyrównanie do prawej
VStack(alignment: .leading)
Dla HStack:
.top — umieszcza elementy na górze stosu
.bottom — umieszcza elementy na dole stosu
.center — umieszcza elementy na środku
HStack(alignment: .leading)
Dla ZStack:
Przyjmuje takie same wartości jak dla VStack i HStack, np: leading lub top
Lub kombinacje: topLeading, topTrailing, bottomLeading, bottomTrailing
Odstęp
Żeby ustawić odpowiedni odstęp między elementami stosu, użyj właściwości: spacing.
Ten wrapper służy do wymiany danych między wieloma widokami. Jest to szczególnie przydatne kiedy jeden widok składa się z wielu innych i na przykład do niektórych z nich musimy przekazać jakieś dane.
Przekazywanie danych z jednego widoku do drugiego, aż w końcu trafimy na ten, w którym te dane są potrzebne, staje się męczące. Ten problem rozwiązuje @EnvironmentObject.
Masz także gwarancję, że jeśli dane się zmienią, widok zostanie automatycznie o tym poinformowany.
Aby przejąć dane oznaczone przez @EnvironmentObject, będziesz musiał w widoku, który znajduje się wyżej w hierarchii wywołać metodę environmentObject i przekazać do niej obiekt, którym chcesz się dzielić z innymi widokami.
Najlepiej wszystko zobrazuje poniższy przykład.
Przykład
Mamy jeden model o nazwie Counter.
Trzy widoki w takiej hierarchii: ContentView -> InformationView -> CounterLabelView.
Widok CounterLabelView potrzebuje mieć dostęp do obiektu klasy Counter. Dlatego w tym widoku zostanie użyty @EnvironmentObject, aby przechwycić przesłane dane.
W widoku InformationView niepotrzebny jest obiekt klasy Counter. Zawiera on widok CounterLabelView.
W widoku głównym ContentView wywołujemy metodę environmentObject, żeby przekazać instancję klasy Counter do widoków potomnych.
Model:
import SwiftUI
classCounter: ObservableObject{
@Publishedvar value: Int = 0funcincrement() {
value += 1
}
funcdecrement() {
value -= 1
}
funcreset() {
value = 0
}
}