reklama - zainteresowany?

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

Programowanie funkcyjne w języku C#. Jak pisać lepszy kod
ebook
Autor: Enrico Buonanno
Tłumaczenie: Witold Sikorski, Małgorzata Dąbkowska-Kowalik
ISBN: 978-83-012-0846-2
stron: 450, Format: ebook
Data wydania: 2020-11-17
Księgarnia: Helion

Cena książki: 71,20 zł (poprzednio: 87,90 zł)
Oszczędzasz: 19% (-16,70 zł)

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

Tagi: C# - Programowanie

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.

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

 

Osoby które kupowały "Programowanie funkcyjne w języku C#. Jak pisać lepszy kod", wybierały także:

  • Domain-Driven Design dla .NET Core. Jak rozwiązywać złożone problemy podczas projektowania architektury aplikacji
  • Gray Hat C#. Język C# w kontroli i łamaniu zabezpieczeń
  • Platforma Xamarin. Kurs video. Poziom drugi. Zaawansowane techniki tworzenia aplikacji cross-platform
  • Wzorce projektowe dla programistów C#. Kurs video
  • WPF. Kurs video. Om

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

Spis treści

Programowanie funkcyjne w języku C#. Jak pisać lepszy kod eBook -- spis treści

  • Okładka
  • Strona tytułowa
  • Strona redakcyjna
  • Spis treści
  • Wprowadzenie
  • Podziękowania
  • O książce
  • Część I Podstawowe pojęcia
    • 1. Wprowadzenie do programowania funkcyjnego
      • 1.1 Czym jest to, co nazywamy programowaniem funkcyjnym?
        • 1.1.1 Funkcje jako elementy pierwszoklasowe
        • 1.1.2 Unikanie zmiany stanu
        • 1.1.3 Pisanie programów o silnych gwarancjach
      • 1.2 W jakim stopniu język C# jest funkcyjny?
        • 1.2.1 Funkcyjna natura LINQ
        • 1.2.2 Elementy funkcyjne w C# 6 i C# 7
        • 1.2.3 Bardziej funkcyjna przyszłość dla języka C#?
      • 1.3 Myślenie w kategoriach funkcji
        • 1.3.1 Funkcje jako odwzorowania
        • 1.3.2 Reprezentacja funkcji w C#
      • 1.4 Funkcje wyższego rzędu
        • 1.4.1 Funkcje zależne od innych funkcji
        • 1.4.2 Funkcje adapterowe
        • 1.4.3 Funkcje, które tworzą inne funkcje
      • 1.5 Używanie funkcji HOF do unikania duplikacji
        • 1.5.1 Enkapsulacja przygotowania i zwolnienia w HOF
        • 1.5.2 Włączanie instrukcji using do HOF
        • 1.5.3 Kompromisy HOF
      • 1.6 Korzyści wynikające z programowania funkcyjnego
      • Ćwiczenia
      • Podsumowanie
    • 2. Dlaczego czystość funkcji ma znaczenie
      • 2.1 Czym jest czystość funkcji?
        • 2.1.1 Czystość i efekty uboczne
        • 2.1.2 Strategie zarządzania efektami ubocznymi
      • 2.2 Czystość i współbieżność
        • 2.2.1 Czyste funkcje są dobre do równoległego przetwarzania
        • 2.2.2 Równoległe wykonywanie funkcji nieczystych
        • 2.2.3 Unikanie zmiany stanu
      • 2.3 Czystość i testowalność
        • 2.3.1 W praktyce: scenariusz walidacji
        • 2.3.2 Testowanie funkcji nieczystych
        • 2.3.3 Dlaczego testowanie nieczystych funkcji jest trudne
        • 2.3.4 Parametryzowane testy jednostkowe
        • 2.3.5 Unikanie interfejsów nagłówkowych
      • 2.4 Czystość a ewolucja obliczeń
      • Ćwiczenia
      • Podsumowanie
    • 3. Projektowanie sygnatur funkcji i typów
      • 3.1 Projektowanie sygnatury funkcji
        • 3.1.1 Notacja strzałkowa
        • 3.1.2 Ile informacji niesie sygnatura?
      • 3.2 Przechwytywanie danych za pomocą obiektów danych
        • 3.2.1 Typy podstawowe często nie są dostatecznie konkretne
        • 3.2.2 Ograniczenie wejść za pomocą typów niestandardowych
        • 3.2.3 Pisanie uczciwych funkcji
        • 3.2.4 Łączenie wartości za pomocą krotek i obiektów
      • 3.3 Modelowanie braku danych za pomocą Unit
        • 3.3.1 Dlaczego void nie jest idealny
        • 3.3.2 Usuwanie luki między Action a Func za pomocą Unit
      • 3.4 Modelowanie możliwego braku danych za pomocą Option
        • 3.4.1 Kiepskie API, których używamy na co dzień
        • 3.4.2 Wprowadzenie do typu Option
        • 3.4.3 Implementacja Option
        • 3.4.4 Większa niezawodność dzięki zastosowaniu Option zamiast null
        • 3.4.5 Option jako naturalny typ wyniku funkcji częściowych
      • Ćwiczenia
      • Podsumowanie
    • 4. Wzorce w programowaniu funkcyjnym
      • 4.1 Stosowanie funkcji do wewnętrznych wartości struktury
        • 4.1.1 Odwzorowanie funkcji na elementach ciągu
        • 4.1.2 Odwzorowanie funkcji na Option
        • 4.1.3 Jak Option zwiększa poziom abstrakcji
        • 4.1.4 Wprowadzenie do funktorów
      • 4.2 Wykonywanie efektów ubocznych za pomocą ForEach
      • 4.3 Łączenie funkcji za pomocą Bind
        • 4.3.1 Połączenie ze sobą funkcji zwracających Option
        • 4.3.2 Spłaszczanie zagnieżdżonych list za pomocą Bind
        • 4.3.3 To nazywamy monadą!
        • 4.3.4 Funkcja Return
        • 4.3.5 Relacje między funktorami a monadami
      • 4.4 Filtrowanie wartości za pomocą Where
      • 4.5 Połączenie Option i IEnumerable za pomocą Bind
      • 4.6 Kodowanie na różnych poziomach abstrakcji
        • 4.6.1 Wartości regularne a podniesione
        • 4.6.2 Przekraczanie poziomów abstrakcji
        • 4.6.3 Map kontra Bind ponownie
        • 4.6.4 Praca na właściwym poziomie abstrakcji
      • Ćwiczenia
      • Podsumowanie
    • 5. Projektowanie programów za pomocą składania funkcji
      • 5.1 Złożenie funkcji
        • 5.1.1 Przegląd informacji o złożeniu funkcji
        • 5.1.2 Łańcuch metod
        • 5.1.3 Złożenie w świecie podwyższonego poziomu
      • 5.2 Myślenie w kategoriach przepływu danych
        • 5.2.1 Używanie składalnego API z LINQ
        • 5.2.2 Pisanie funkcji, które łatwo podlegają złożeniu
      • 5.3 Programowanie przepływów pracy
        • 5.3.1 Prosty przepływ pracy w celu weryfikacji
        • 5.3.2 Refaktoryzacja z uwględnieniem przepływu danych
        • 5.3.3 Złożenie prowadzi do większej elastyczności
      • 5.4 Wprowadzenie do funkcyjnego modelowania dziedziny
      • 5.5 Kompleksowy przepływ pracy po stronie serwera
        • 5.5.1 Wyrażenia kontra instrukcje
        • 5.5.2 Deklaratywnie kontra imperatywnie
        • 5.5.3 Funkcyjne spojrzenie na warstwy
      • Ćwiczenia
      • Podsumowanie
  • Część II W stronę funkcyjności
    • 6. Funkcyjne obsługiwanie błędów
      • 6.1 Bezpieczniejszy sposób przedstawiania wyników
        • 6.1.1 Uchwycenie szczegółów dotyczących błędów za pomocą Either
        • 6.1.2 Podstawowe funkcje do wykorzystania z Either
        • 6.1.3 Porównanie Option i Either
      • 6.2 Łączenie działań, które mogą się nie udać
      • 6.3 Walidacja: doskonały przypadek zastosowania Either
        • 6.3.1 Wybór odpowiedniej reprezentacji dla błędów
        • 6.3.2 Definiowanie API opartego na Either
        • 6.3.3 Dodawanie kodu walidacji
      • 6.4 Przedstawianie wyników aplikacjom klienckim
        • 6.4.1 Udostępnianie interfejsu typu Option
        • 6.4.2 Udostępnianie interfejsu typu Either
        • 6.4.3 Zwracanie wynikowego obiektu (DTO)
      • 6.5 Wariacje na temat Either
        • 6.5.1 Zmiana reprezentacji błędów
        • 6.5.2 Specjalizowane wersje Either
        • 6.5.3 Refaktoryzacja do Validation i Exceptional
        • 6.5.4 Odejście od wyjątków?
      • Ćwiczenia
      • Podsumowanie
    • 7. Budowanie aplikacji za pomocą funkcji
      • 7.1 Aplikacja częściowa: dostarczanie fragmentów argumentów
        • 7.1.1 Ręczne włączanie częściowej aplikacji
        • 7.1.2 Uogólnianie aplikacji częściowej
        • 7.1.3 Kolejność argumentów ma znaczenie
      • 7.2 Pokonywanie kaprysów rozwiązywania metod
      • 7.3 Funkcje rozwinięte: zoptymalizowane pod kątem częściowej aplikacji
      • 7.4 Tworzenie API przyjaznego dla aplikacji częściowej
        • 7.4.1 Typy jako dokumentacja
        • 7.4.2 Wyszczególnianie funkcji dostępu do danych
      • 7.5 Modularyzacja i budowanie aplikacji
        • 7.5.1 Modułowość w programowaniu obiektowym
        • 7.5.2 Modułowość w FP
        • 7.5.3 Porównanie dwóch podejść
        • 7.5.4 Budowanie aplikacji
      • 7.6 Redukowanie listy do jednej wartości
        • 7.6.1 Metoda Aggregate w LINQ
        • 7.6.2 Agregowanie wyników walidacji
        • 7.6.3 Zbieranie błędów walidacji
      • Ćwiczenia
      • Podsumowanie
    • 8. Efektywne wykorzystywanie funkcji wieloargumentowych
      • 8.1 Aplikacja funkcji w świecie podniesionych typów
        • 8.1.1 Zrozumienie aplikatyw
        • 8.1.2 Podnoszenie poziomu funkcji
        • 8.1.3 Wprowadzenie do testowania opartego na własnościach
      • 8.2 Funktory, aplikatywy, monady
      • 8.3 Prawa monad
        • 8.3.1 Prawa tożsamość
        • 8.3.2 Lewa tożsamość
        • 8.3.3 Łączność
        • 8.3.4 Używanie Bind z funkcjami wieloargumentowymi
      • 8.4 Poprawianie czytelności przez użycie LINQ z dowolną monadą
        • 8.4.1 Korzystanie z LINQ z arbitralnymi funktorami
        • 8.4.2 Używanie LINQ z dowolnymi monadami
        • 8.4.3 let, where i inne klauzule LINQ
      • 8.5 Kiedy używać Bind, a kiedy Apply
        • 8.5.1 Walidacja za pomocą inteligentnych konstruktorów
        • 8.5.2 Zbieranie błędów za pomocą przepływu aplikatywnego
        • 8.5.3 Szybka porażka przy przepływie monadycznym
      • Ćwiczenia
      • Podsumowanie
    • 9. Rozważania o funkcyjności danych
      • 9.1 Pułapki mutacji stanu
      • 9.2 Zrozumienie stanu, tożsamości i zmiany
        • 9.2.1 Niektóre rzeczy nigdy się nie zmieniają
        • 9.2.2 Reprezentowanie zmian bez mutacji
      • 9.3 Wymuszanie niemutowalności
        • 9.3.1 Całkowita niemutowalność
        • 9.3.2 Metody kopiowania bez szablonowego kodu?
        • 9.3.3 Wykorzystywanie F# do typów danych
        • 9.3.4 Porównywanie strategii dla niemutowalności: konkurs brzydoty
      • 9.4 Krótkie wprowadzenie do funkcyjnych struktur danych
        • 9.4.1 Klasyczna lista wiązana w stylu funkcyjnym
        • 9.4.2 Drzewa binarne
      • Ćwiczenia
      • Podsumowanie
    • 10. Event sourcing: funkcyjne podejście do zapisu
      • 10.1 Funkcyjne rozważania o przechowywaniu danych
        • 10.1.1 Dlaczego przechowywanie danych powinno polegać wyłącznie na ich dołączaniu
        • 10.1.2 Zrelaksujmy się i zapomnijmy o przechowywaniu stanu
      • 10.2 Podstawy event sourcingu
        • 10.2.1 Reprezentacja zdarzeń
        • 10.2.2 Przechowywanie zdarzeń
        • 10.2.3 Reprezentacja stanu
        • 10.2.4 Przerwa na dopasowywanie do wzorca
        • 10.2.5 Reprezentacja zmian stanu
        • 10.2.6 Odtwarzanie bieżącego stanu na podstawie przeszłych zdarzeń
      • 10.3 Architektura systemu opartego na zdarzeniach
        • 10.3.1 Obsługa poleceń
        • 10.3.2 Obsługa zdarzeń
        • 10.3.3 Dodanie walidacji
        • 10.3.4 Tworzenie widoków danych na podstawie zdarzeń
      • 10.4 Porównanie różnych podejść do niemutowalnego magazynu
        • 10.4.1 Datomic kontra Event Store
        • 10.4.2 Jak bardzo nasza dziedzina jest sterowana zdarzeniami?
      • Podsumowanie
  • Część III Zaawansowane techniki
    • 11. Leniwe wartościowanie, kontynuacje oraz piękno kompozycji monadycznej
      • 11.1 Zalety leniwego wartościowania
        • 11.1.1 Leniwe API działające z Option
        • 11.1.2 Złożenie leniwych wartościowań
      • 11.2 Obsługa wyjątków za pomocą Try
        • 11.2.1 Reprezentowanie obliczeń, które mogą się nie powieść
        • 11.2.2 Bezpieczne pobieranie informacji z obiektu JSON
        • 11.2.3 Złożenia obliczeń, które mogą się nie udać
        • 11.2.4 Złożenie monadyczne: co to znaczy?
      • 11.3 Tworzenie potoku oprogramowania pośredniczącego na potrzeby dostępu do bazy danych
        • 11.3.1 Złożenie funkcji, które inicjalizują/czyszczą
        • 11.3.2 Przepis na uniknięcie piramidy potępienia
        • 11.3.3 Przechwycenie istoty oprogramowania pośredniczącego
        • 11.3.4 Implementacja wzorca zapytania dla oprogramowania pośredniczącego
        • 11.3.5 Dodawanie oprogramowania pośredniczącego, które mierzy czas działania
        • 11.3.6 Dodawanie oprogramowania pośredniczącego zarządzającego transakcją
      • Podsumowanie
    • 12. Stanowe programy i obliczenia
      • 12.1 Programy, które zarządzają stanem
        • 12.1.1 Utrzymywanie pamięci podręcznej uzyskanych zasobów
        • 12.1.2 Refaktoryzacja w celu umożliwienia testowania i obsługi błędów
        • 12.1.3 Obliczenia stanowe
      • 12.2 Język do generowania danych losowych
        • 12.2.1 Generowanie całkowitych liczb losowych
        • 12.2.2 Generowanie innych wartości podstawowych
        • 12.2.3 Generowanie bardziej złożonych struktur
      • 12.3 Ogólny wzorzec obliczeń stanowych
      • Podsumowanie
    • 13. Posługiwanie się obliczeniami asynchronicznymi
      • 13.1 Obliczenia asynchroniczne
        • 13.1.1 Potrzeba działania asynchronicznego
        • 13.1.2 Reprezentowanie działań asynchronicznych za pomocą Task
        • 13.1.3 Zadanie jako kontener na przyszłą wartość
        • 13.1.4 Obsługa błędów
        • 13.1.5 API HTTP API dla konwersji walut
        • 13.1.6 W razie niepowodzenia próbujmy kilka razy
        • 13.1.7 Równoległe uruchamianie działań asynchronicznych
      • 13.2 Funkcje przesuwne: praca z listami podniesionych wartości
        • 13.2.1 Weryfikacja listy wartości za pomocą monadycznej funkcji Traverse
        • 13.2.2 Zbieranie błędów walidacji za pomocą aplikatywnej funkcji Traverse
        • 13.2.3 Zastosowanie wielu walidatorów do jednej wartości
        • 13.2.4 Stosowanie Traverse z Task, jeśli możliwych jest wiele wyników
        • 13.2.5 Definiowanie Traverse dla struktur o pojedynczej wartości
      • 13.3 Łączenie asynchroniczności i walidacji (lub dowolnych innych efektów monadycznych)
        • 13.3.1 Problem złożenia monad
        • 13.3.2 Zmniejszenie liczby efektów
        • 13.3.3 Wyrażenia LINQ ze złożeniem monad
      • Podsumowanie
    • 14. Strumienie danych i Reactive Extensions
      • 14.1 Reprezentowanie strumieni danych za pomocą IObservable
        • 14.1.1 Ciąg wartości w czasie
        • 14.1.2 Subskrypcja IObservable
      • 14.2 Tworzenie IObservables
        • 14.2.1 Tworzenie zegara
        • 14.2.2 Używanie Subject, aby poinformować IObservable, kiedy ma wysyłać sygnał
        • 14.2.3 Tworzenie IObservables na podstawie subskrypcji opartych na wywołaniach zwrotnych
        • 14.2.4 Tworzenie IObservables z prostszych struktur
      • 14.3 Przekształcanie i łączenie strumieni danych
        • 14.3.1 Przekształcenia strumienia
        • 14.3.2 Łączenie i podział strumieni
        • 14.3.3 Obsługa błędów w IObservable
        • 14.3.4 Składamy wszystko razem
      • 14.4 Implementacja kodu, który łączy wiele zdarzeń
        • 14.4.1 Wykrywanie ciągów naciśnięć klawiszy
        • 14.4.2 Reagowanie na wiele źródeł zdarzeń
        • 14.4.3 Powiadamianie, kiedy na koncie pojawia się debet
      • 14.5 Kiedy należy stosować IObservable?
      • Podsumowanie
    • 15. Wprowadzenie do współbieżności z przesyłaniem komunikatów
      • 15.1 Zapotrzebowanie na współdzielony stan mutowalny
      • 15.2 Zrozumienie współbieżności z przesyłaniem komunikatów
        • 15.2.1 Implementowanie agentów w C#
        • 15.2.2 Pierwsze kroki z agentami
        • 15.2.3 Użycie agentów do obsługi równoczesnych żądań
        • 15.2.4 Agenty kontra aktory
      • 15.3 Funkcyjne API, implementacje oparte na agentach
        • 15.3.1 Agenty jako szczegóły implementacji
        • 15.3.2 Ukrywanie agentów za tradycyjnym API
      • 15.4 Współbieżność z przesyłaniem komunikatów w aplikacjach LOB
        • 15.4.1 Korzystanie z agenta do synchronizacji dostępu do danych konta
        • 15.4.2 Przechowywanie rejestru kont
        • 15.4.3 Agent nie jest obiektem
        • 15.4.4 Łączenie wszystkiego ze sobą
      • Podsumowanie
  • Epilog: co dalej?
  • Przypisy

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

Code, Publish & WebDesing by CATALIST.com.pl



(c) 2005-2024 CATALIST agencja interaktywna, znaki firmowe należą do wydawnictwa Helion S.A.