Programowanie funkcyjne w języku C#. Jak pisać lepszy kod

1 opinia

Format:

epub, mobi, ibuk

DODAJ DO ABONAMENTU

WYBIERZ RODZAJ DOSTĘPU

66,75  89,00

Format: epub, mobi

 

Dostęp online przez myIBUK

WYBIERZ DŁUGOŚĆ DOSTĘPU

6,15

Wypożycz na 24h i opłać sms-em

66,7589,00

cena zawiera podatek VAT

ZAPŁAĆ SMS-EM

TA KSIĄŻKA JEST W ABONAMENCIE

Już od 19,90 zł miesięcznie za 5 ebooków!

WYBIERZ SWÓJ ABONAMENT

Programowanie funkcyjne zmienia sposób myślenia o kodzie!
W przypadku developerów C# techniki programowania funkcyjnego mogą znacznie poprawić zarządzanie stanem, współbieżność, obsługę wyjątków i długoterminowe utrzymywanie kodu. C# oferuje także elastyczność, która pozwala w pełni korzystać z zastosowania technik funkcyjnych. Ta książka daje niesamowitą moc nowej perspektywy.
Programowanie funkcyjne w języku C# uczy, jak stosować funkcyjne podejście do rzeczywistych problemów, korzystając z języka C#. Na początku nauczysz się podstaw programowania funkcyjnego i własności języka, które pozwalają programować w sposób funkcyjny. Poprzez analizę wielu praktycznych przykładów, poznasz siłę składania funkcji, programowania przepływu danych, niemutowalnych struktur danych oraz składania monadycznego za pomocą LINQ.
Książka omawia następujące tematy:
pisanie czytelnego, przyjaznego dla zespołu kodu, opanowanie strumieni asynchronicznych i strumieni danych, zdecydowana poprawa obsługi błędów, event sourcing i inne wzorce programowania funkcyjnego. Lektura dla zaawansowanych programistów C# bez wcześniejszego doświadczenia w programowaniu funkcyjnym.


Liczba stron450
WydawcaWydawnictwo Naukowe PWN
TłumaczenieMałgorzata Dąbkowska-Kowalik, Witold Sikorski
ISBN-13978-83-01-20846-2
Numer wydania1
Język publikacjipolski
Informacja o sprzedawcyePWN sp. z o.o.

Ciekawe propozycje

Spis treści

  wprowadzenie xvii
  podziękowania xix
  o książce xxi
  CZĘŚĆ I. PODSTAWOWE POJĘCIA 1
  1. Wprowadzenie do programowania funkcyjnego 3
    1.1 Czym jest to, co nazywamy programowaniem funkcyjnym?    4
    Funkcje jako elementy pierwszoklasowe    4
    Unikanie zmiany stanu    5
    Pisanie programów o silnych gwarancjach    6
    1.2 W jakim stopniu język C# jest funkcyjny?    9
    Funkcyjna natura LINQ    10
    Elementy funkcyjne w C# 6 i C# 7    11
    Bardziej funkcyjna przyszłość dla języka C#?    13
    1.3 Myślenie w kategoriach funkcji    14
    Funkcje jako odwzorowania    14
    Reprezentacja funkcji w C#    15
    1.4 Funkcje wyższego rzędu    19
    Funkcje zależne od innych funkcji    20
    Funkcje adapterowe    22
    Funkcje, które tworzą inne funkcje    22
    1.5 Używanie funkcji HOF do unikania duplikacji    23
    Enkapsulacja przygotowania i zwolnienia w HOF    25
    Włączanie instrukcji using do HOF    26
    Kompromisy HOF    28
    1.6 Korzyści wynikające z programowania funkcyjnego    29
  2. Dlaczego czystość funkcji ma znaczenie 32
    2.1 Czym jest czystość funkcji?    33
    Czystość i efekty uboczne    33
    Strategie zarządzania efektami ubocznymi    34
    2.2 Czystość i współbieżność    37
    Czyste funkcje są dobre do równoległego przetwarzania    38
    Równoległe wykonywanie funkcji nieczystych    39
    Unikanie zmiany stanu    40
    2.3 Czystość i testowalność    42
    W praktyce: scenariusz walidacji    43
    Testowanie funkcji nieczystych    45
    Dlaczego testowanie nieczystych funkcji jest trudne    46
    Parametryzowane testy jednostkowe    48
    Unikanie interfejsów nagłówkowych    49
    2.4 Czystość a ewolucja obliczeń    52
  3. Projektowanie sygnatur funkcji i typów    54
    3.1 Projektowanie sygnatury funkcji    55
    Notacja strzałkowa    55
    Ile informacji niesie sygnatura?    56
    3.2 Przechwytywanie danych za pomocą obiektów danych    57
    Typy podstawowe często nie są dostatecznie konkretne    58
    Ograniczenie wejść za pomocą typów niestandardowych    59
    Pisanie „uczciwych” funkcji    61
    Łączenie wartości za pomocą krotek i obiektów    62
    3.3 Modelowanie braku danych za pomocą Unit    63
    Dlaczego void nie jest idealny    64
    Usuwanie luki między Action a Func za pomocą
    Unit    65
    3.4 Modelowanie możliwego braku danych za pomocą Option    67
    Kiepskie API, których używamy na co dzień    67
    Wprowadzenie do typu
    Option    68
    Implementacja Option    71
    Większa niezawodność dzięki zastosowaniu
    Option zamiast null    74
    Option jako naturalny typ wyniku funkcji częściowych    75
  4. Wzorce w programowaniu funkcyjnym    82
    4.1 Stosowanie funkcji do wewnętrznych wartości struktury    82
    Odwzorowanie funkcji na elementach ciągu    83
    Odwzorowanie funkcji na
    Option    83
    Jak Option zwiększa poziom abstrakcji    86
    Wprowadzenie do funktorów    87
    4.2 Wykonywanie efektów ubocznych za pomocą ForEach    88
    4.3 Łączenie funkcji za pomocą Bind    90
    Połączenie ze sobą funkcji zwracających Option    91
    Spłaszczanie zagnieżdżonych list za pomocą Bind    92
    To nazywamy monadą!    94
    Funkcja Return    94
    Relacje między funktorami a monadami    95
    4.4 Filtrowanie wartości za pomocą Where    95
    4.5 Połączenie Option i IEnumerable za pomocą Bind    96
    4.6 Kodowanie na różnych poziomach abstrakcji    98
    Wartości regularne a podniesione    99
    Przekraczanie poziomów abstrakcji    100
    Map kontra Bind – ponownie    101
    Praca na właściwym poziomie abstrakcji    102
  5. Projektowanie programów za pomocą składania funkcji 104
    5.1 Złożenie funkcji    105
    Przegląd informacji o złożeniu funkcji    105
    Łańcuch metod    106
    Złożenie w świecie podwyższonego poziomu    106
    5.2 Myślenie w kategoriach przepływu danych    107
    Używanie składalnego API z LINQ    108
    Pisanie funkcji, które łatwo podlegają złożeniu    109
    5.3 Programowanie przepływów pracy    111
    Prosty przepływ pracy w celu weryfi kacji    112
    Refaktoryzacja z uwględnieniem przepływu danych    113
    Złożenie prowadzi do większej elastyczności    114
    5.4 Wprowadzenie do funkcyjnego modelowania dziedziny    115
    5.5 Kompleksowy przepływ pracy po stronie serwera    116
    Wyrażenia kontra instrukcje    118
    Deklaratywnie kontra imperatywnie    119
    Funkcyjne spojrzenie na warstwy    120
  CZĘŚĆ II. W STRONĘ FUNKCYJNOŚCI 123
  6. Funkcyjne obsługiwanie błędów 125
    6.1 Bezpieczniejszy sposób przedstawiania wyników    126
    Uchwycenie szczegółów dotyczących błędów za pomocą Either    127
    Podstawowe funkcje do wykorzystania z Either    130
    Porównanie Option i Either    131
    6.2 Łączenie działań, które mogą się nie udać    132
    6.3 Walidacja: doskonały przypadek zastosowania Either    135
    Wybór odpowiedniej reprezentacji dla błędów    135
    Defi niowanie API opartego na Either    136
    Dodawanie kodu walidacji    137
    6.4 Przedstawianie wyników aplikacjom klienckim    138
    Udostępnianie interfejsu typu Option    140
    Udostępnianie interfejsu typu Either    141
    Zwracanie wynikowego obiektu (DTO)    142
    6.5 Wariacje na temat Either    143
    Zmiana reprezentacji błędów    144
    Specjalizowane wersje Either    145
    Refaktoryzacja do Validation i Exceptional    146
    Odejście od wyjątków?    149
  7. Budowanie aplikacji za pomocą funkcji    152
    7.1 Aplikacja częściowa: dostarczanie fragmentów argumentów    153
    Ręczne włączanie częściowej aplikacji    155
    Uogólnianie aplikacji częściowej    156
    Kolejność argumentów ma znaczenie    157
    7.2 Pokonywanie kaprysów rozwiązywania metod    158
    7.3 Funkcje rozwinięte: zoptymalizowane pod kątem częściowej aplikacji    160
    7.4 Tworzenie API przyjaznego dla aplikacji częściowej    163
    Typy jako dokumentacja    165
    Wyszczególnianie funkcji dostępu do danych    166
    7.5 Modularyzacja i budowanie aplikacji    168
    Modułowość w programowaniu obiektowym    168
    Modułowość w FP    170
    Porównanie dwóch podejść    173
    Budowanie aplikacji    174
    7.6 Redukowanie listy do jednej wartości    175
    Metoda Aggregate w LINQ    175
    Agregowanie wyników walidacji    177
    Zbieranie błędów walidacji    178
  8. Efektywne wykorzystywanie funkcji wieloargumentowych 181
    8.1 Aplikacja funkcji w świecie podniesionych typów    182
    Zrozumienie aplikatyw 184 Podnoszenie poziomu funkcji    186
    Wprowadzenie do testowania opartego na własnościach    187
    8.2 Funktory, aplikatywy, monady    190
    8.3 Prawa monad    192
    Prawa tożsamość    192
    Lewa tożsamość    192
    Łączność    193
    Używanie Bind z funkcjami wieloargumentowymi    195
    8.4 Poprawianie czytelności przez użycie LINQ z dowolną monadą    195
    Korzystanie z LINQ z arbitralnymi funktorami    196
    Używanie LINQ z dowolnymi monadami    197
    let, where i inne klauzule LINQ    201
    8.5 Kiedy używać Bind, a kiedy Apply    202
    Walidacja za pomocą inteligentnych konstruktorów    202
    Zbieranie błędów za pomocą przepływu aplikatywnego    203
    Szybka porażka przy przepływie monadycznym    205
  9. Rozważania o funkcyjności danych    208
    9.1 Pułapki mutacji stanu    209
    9.2 Zrozumienie stanu, tożsamości i zmiany    212
    Niektóre rzeczy nigdy się nie zmieniają 212 Reprezentowanie zmian bez mutacji    214
    9.3 Wymuszanie niemutowalności    217
    Całkowita niemutowalność 219 Metody kopiowania bez szablonowego kodu?    220
    Wykorzystywanie F# do typów danych 222 Porównywanie strategii dla niemutowalności: konkurs brzydoty    224
    9.4 Krótkie wprowadzenie do funkcyjnych struktur danych    225
    Klasyczna lista wiązana w stylu funkcyjnym 226 Drzewa binarne    231
  10. Event sourcing: funkcyjne podejście do zapisu 237
    10.1 Funkcyjne rozważania o przechowywaniu danych    238
    Dlaczego przechowywanie danych powinno polegać wyłącznie na ich dołączaniu    239
    Zrelaksujmy się i zapomnijmy o przechowywaniu stanu    239
    10.2 Podstawy event sourcingu    241
    Reprezentacja zdarzeń    241
    Przechowywanie zdarzeń    242
    Reprezentacja stanu    243
    Przerwa na dopasowywanie do wzorca    244
    Reprezentacja zmian stanu    247
    Odtwarzanie bieżącego stanu na podstawie przeszłych zdarzeń    248
    10.3 Architektura systemu opartego na zdarzeniach    249
    Obsługa poleceń    251
    Obsługa zdarzeń    254
    Dodanie walidacji    255
    Tworzenie widoków danych na podstawie zdarzeń    257
    10.4 Porównanie różnych podejść do niemutowalnego magazynu    260
    Datomic kontra Event Store 261 Jak bardzo nasza dziedzina jest sterowana zdarzeniami?    262
  CZĘŚĆ III. ZAAWANSOWANE TECHNIKI     265
  11. Leniwe wartościowanie, kontynuacje oraz piękno kompozycji monadycznej    267
    11.1 Zalety leniwego wartościowania    268
    Leniwe API działające z Option    268
    Złożenie leniwych wartościowań    271
    11.2 Obsługa wyjątków za pomocą Try    273
    Reprezentowanie obliczeń, które mogą się nie powieść    273
    Bezpieczne pobieranie informacji z obiektu JSON    274
    Złożenia obliczeń, które mogą się nie
    udać 275 Złożenie monadyczne: co to znaczy?    277
    11.3 Tworzenie potoku oprogramowania pośredniczącego na potrzeb dostępu do bazy danych    278
    Złożenie funkcji, które inicjalizują/czyszczą    278
    Przepis na uniknięcie piramidy potępienia Przechwycenie istoty oprogramowania pośredniczącego    280
    Implementacja wzorca zapytania dla oprogramowania pośredniczącego    282
    Dodawanie oprogramowania pośredniczącego, które mierzy czas działania    286
    Dodawanie oprogramowania pośredniczącego zarządzającego transakcją    287
  12. Stanowe programy i obliczenia    290
    12.1 Programy, które zarządzają stanem    291
    Utrzymywanie pamięci podręcznej uzyskanych zasobów    292
    Refaktoryzacja w celu umożliwienia testowania i obsługi błędów    294
    Obliczenia stanowe    296
    12.2 Język do generowania danych losowych    297
    Generowanie całkowitych liczb losowych    298
    Generowanie innych wartości podstawowych    298
    Generowanie bardziej złożonych struktur    300
    12.3 Ogólny wzorzec obliczeń stanowych    302
  13. Posługiwanie się obliczeniami asynchronicznymi 306
    13.1 Obliczenia asynchroniczne    307
    Potrzeba działania asynchronicznego    307
    Reprezentowanie działań asynchronicznych za pomocą Task    308
    Zadanie jako kontener na przyszłą wartość    309
    Obsługa błędów    311
    API HTTP API dla konwersji walut    313
    W razie niepowodzenia próbujmy kilka razy    314
    Równoległe uruchamianie działań asynchronicznych    315
    13.2 Funkcje przesuwne: praca z listami podniesionych wartości    317
    Weryfikacja listy wartości za pomocą monadycznej funkcji Traverse    319
    Zbieranie błędów walidacji za pomocą aplikatywnej funkcji Traverse    320
    Zastosowanie wielu walidatorów do jednej wartości    322
    Stosowanie Traverse z Task, jeśli możliwych jest wiele wyników    323
    Definiowanie Traverse dla struktur o pojedynczej wartości    325
    13.3 Łączenie asynchroniczności i walidacji (lub dowolnych innych efektów monadycznych)    326
    Problem złożenia monad    326
    Zmniejszenie liczby efektów    328
    Wyrażenia LINQ ze złożeniem monad    329
    14 Strumienie danych i Reactive Extensions    332
    14.1 Reprezentowanie strumieni danych za pomocą IObservable    333
    Ciąg wartości w czasie    333
    Subskrypcja IObservable    335
    14.2 Tworzenie IObservables    336
    Tworzenie zegara    336
    Używanie Subject, aby poinformować IObservable, kiedy ma wysyłać sygnał    337
    Tworzenie IObservables na podstawie subskrypcji opartych na wywołaniach zwrotnych    338
    Tworzenie IObservables z prostszych struktur    339
    14.3 Przekształcanie i łączenie strumieni danych    340
    Przekształcenia strumienia    340
    Łączenie i podział strumieni    342
    Obsługa błędów w IObservable    344
    Składamy wszystko razem    346
    14.4 Implementacja kodu, który łączy wiele zdarzeń    347
    Wykrywanie ciągów naciśnięć klawiszy    348
    Reagowanie na wiele źródeł zdarzeń    350
    Powiadamianie, kiedy na koncie pojawia się debet    352
    14.5 Kiedy należy stosować IObservable?    355
  15. Wprowadzenie do współbieżności z przesyłaniem komunikatów 357
    15.1 Zapotrzebowanie na współdzielony stan mutowalny    358
    15.2 Zrozumienie współbieżności z przesyłaniem komunikatów    359
    Implementowanie agentów w C#    362
    Pierwsze kroki z agentami    363
    Użycie agentów do obsługi równoczesnych żądań    365
    Agenty kontra aktory    368
    15.3 Funkcyjne API, implementacje oparte na agentach    370
    Agenty jako szczegóły implementacji    371
    Ukrywanie agentów za tradycyjnym API    372
    15.4 Współbieżność z przesyłaniem komunikatów w aplikacjach LOB    373
    Korzystanie z agenta do synchronizacji dostępu do danych konta    374
    Przechowywanie rejestru kont    376
    Agent nie jest obiektem    377
    Łączenie wszystkiego ze sobą    380
  Epilog: co dalej?    383
RozwińZwiń
W celu zapewnienia wysokiej jakości świadczonych przez nas usług, nasz portal internetowy wykorzystuje informacje przechowywane w przeglądarce internetowej w formie tzw. „cookies”. Poruszając się po naszej stronie internetowej wyrażasz zgodę na wykorzystywanie przez nas „cookies”. Informacje o przechowywaniu „cookies”, warunkach ich przechowywania i uzyskiwania dostępu do nich znajdują się w Regulaminie.

Nie pokazuj więcej tego powiadomienia