Spis Treści: Szybki Przegląd
Testowanie kodu – niedoceniany fundament jakości
Testowanie kodu często odkładane są na później, ale pełne testy to inwestycja, która może uchronić Twój projekt przed nieprzewidzianymi błędami.
Ubezpiecz się – stwórz testy na każdą sytuację, nawet te nieoczywiste.
Przykładowy kod wejściowy (C#):
public decimal CalculateTotal(List<Item> cartItems, decimal discount)
{
decimal total = 0;
foreach (var item in cartItems)
{
total += item.Price * item.Quantity;
}
total -= total * (discount / 100);
return total;
}
🤖 Prompt
Napisz zestaw testów jednostkowych w C# dla funkcji CalculateTotal(List<Item> cartItems, decimal discount). Przetestuj przypadki, takie jak pusty koszyk, zerowy oraz ujemny rabat, i sytuację, gdy rabat przekracza 100%. Dodaj przypadki krańcowe dla wartości Price i Quantity.
Czytelność kodu – ułatwia współpracę i rozumienie logiki
Czytelność kodu jest fundamentem pracy zespołowej i skutecznego zarządzania projektem.
Opisowe nazwy zmiennych, klarowne komentarze - to brak nieporozumień i łatwiejsze utrzymanie w dłuższej perspektywie.
Pisząc kod, który jest przejrzysty i zrozumiały, zmniejszasz ryzyko błędów oraz przyspieszasz wdrażanie nowych członków zespołu.
To przełoży się się na wyższą jakość i stabilność projektu.
Przykładowy kod wejściowy (JavaScript):
function calcTotal(items, disc) {
let tot = 0;
items.forEach(item => {
tot += item.price * item.qty;
});
tot -= tot * (disc / 100);
return tot;
}
🤖 Prompt
Zrefaktoryzuj funkcję calcTotal(items, disc) w JavaScript, aby poprawić czytelność. Użyj bardziej opisowych nazw zmiennych, np. items na cartItems, tot na totalAmount, disc na discount. Dodaj komentarze opisujące kroki obliczeń.
Optymalizacja kodu – szybsze działanie dzięki odpowiednim technologiom
Optymalizacja kodu zapewni skalowalność i wysoką wydajność Twojej aplikacji, szczególnie jeśli pracujesz z dużymi zbiorami danych.
Efektywne wykorzystanie struktur danych oraz algorytmów o niskiej złożoności obliczeniowej pozwoli Ci zredukować czas przetwarzania i zmniejszyć zużycie zasobów systemowych.
Przykładowy kod wejściowy (JavaScript):
function processOrders(orders) {
let results = [];
for (let i = 0; i < orders.length; i++) {
results.push(fetchOrderDetails(orders[i]));
}
return Promise.all(results);
}
🤖 Prompt
Zoptymalizuj funkcję processOrders(orders) w JavaScript, aby efektywnie pobierała szczegóły zamówień asynchronicznie, przy użyciu Promise.all() oraz async/await. Użyj for...of z await dla przyspieszenia przetwarzania dużych zestawów zamówień.
Unikaj powielania kodu – refaktoryzacja zwiększa czytelność i utrzymywalność
Duplikacja kodu prowadzi do chaosu, szczególnie w dużych projektach.
Powtarzające się fragmenty kodu zwiększają ryzyko błędów, ponieważ każda zmiana wymaga edycji wielu miejsc.
Przykładowy kod wejściowy (C#):
public decimal CalculateTax(decimal price)
{
return price * 0.2m;
}
public decimal CalculateDiscount(decimal price)
{
return price * 0.1m;
}
public decimal CalculateTotal(decimal price)
{
decimal tax = price * 0.2m;
decimal discount = price * 0.1m;
return price + tax - discount;
}
🤖 Prompt
Zrefaktoryzuj kod w C# tak, aby powtarzające się obliczenia podatku i rabatu były wyodrębnione do jednej metody CalculateAdjustment(decimal price, decimal rate). Wykorzystaj ją w CalculateTax i CalculateDiscount.
Zarządzanie zależnościami – ogranicz liczbę bibliotek i zadbaj o kompatybilność
Zewnętrzne biblioteki bywają bardzo przydatne, ale gdy używamy ich rozsądnie.
Musimy pamiętać o kaskadach zależności, problemach z aktualizacjami czy konfliktami wersji.
Czasem lepiej wykorzystać wbudowane funkcje.
Przykładowy kod wejściowy (JavaScript):
const _ = require('lodash');
function getUniqueItems(items) {
return _.uniqBy(items, 'id');
}
🤖 Prompt
Przepisz funkcję getUniqueItems(items) w JavaScript, aby uniknąć zależności od lodash. Wykorzystaj natywne metody JavaScript do zwracania unikalnych elementów w oparciu o id.
Trzymaj się standardów – ułatwisz współpracę i poprawia jakość projektu
Przestrzeganie standardów kodowania jest ważne dla utrzymania spójności i czytelności kodu.
Ujednolicone konwencje, obejmujące formatowanie, wcięcia czy nazewnictwo, minimalizują ryzyko błędów oraz przyspieszają proces przeglądów kodu.
Przykładowy kod wejściowy (JavaScript):
let price=100; let tax=0.2;let totalPrice=price+price*tax;
console.log(totalPrice);
🤖 Prompt
Skonfiguruj ESLint dla projektu w JavaScript, aby wymusić przestrzeganie standardów kodowania, takich jak spacje wokół operatorów i jednolite formatowanie. Przepisz kod, aby był zgodny z tymi zasadami.
Dokumentacja – kluczowy element ułatwiający pracę zespołową
Dokumentacja jest nieoceniona dla zespołów pracujących nad złożonymi projektami.
Szczególnie tych o dużej skali.
Dobra dokumentacja redukuje potrzebę bezpośrednich konsultacji, wspiera onboarding nowych członków zespołu oraz ułatwia utrzymanie i rozbudowę projektu w długim terminie.
Przykładowy kod wejściowy (C#):
public decimal CalculateDiscount(decimal price, decimal discountRate)
{
return price - (price * discountRate);
}
🤖 Prompt
Napisz komentarz dokumentacyjny dla funkcji CalculateDiscount(decimal price, decimal discountRate) w C#. Opisz parametry, zwracaną wartość oraz potencjalne wyjątki.
Zabezpieczenie przed błędami – program defensywny to program bezpieczny
Błędy związane z niewłaściwymi danymi wejściowymi mogą być trudne do wykrycia.
Program defensywny zakłada, że zawsze może pojawić się nieoczekiwany scenariusz.
Więcej o defensywnym programowaniu pisałem tutaj: Explore the Top 20 Defensive Programming Principles in .NET.
Przykładowy kod wejściowy (C#):
public int Divide(int numerator, int denominator)
{
return numerator / denominator;
}
🤖 Prompt
Zmodyfikuj funkcję Divide(int numerator, int denominator) w C#, aby obsługiwała wyjątki i przypadki, gdy denominator jest zerem. Dodaj wyświetlanie komunikatu o błędzie.
Sprawdzanie poprawności danych – dbaj o jakość danych na wejściu
Weryfikacja poprawności danych wejściowych to klucz do zapewnienia jakości i stabilności aplikacji. Niewłaściwe lub niekompletne dane mogą prowadzić do błędów, które są trudne do wykrycia i naprawy. Szczególnie w późniejszych etapach przetwarzania.
Walidacja danych na etapie wejścia umożliwia szybkie wykrycie nieprawidłowości, redukuje ryzyko wystąpienia błędów oraz podnosi bezpieczeństwo aplikacji.
Przykładowy kod wejściowy (JavaScript):
function addUserToList(userList, user) {
userList.push(user);
}
🤖 Prompt
Rozbuduj funkcję addUserToList(userList, user) w JavaScript, aby walidowała obiekt user, sprawdzając, czy zawiera pola name i email, oraz czy email ma poprawny format.
Obsługa wyjątków – przygotuj kod na niespodziewane błędy
Obsługa wyjątków zapewni stabilność i odporność aplikacji na niespodziewane błędy.
Takie jak: brak dostępu do plików, błędy sieciowe czy problemy z bazą danych.
Przykładowy kod wejściowy (C#):
public string ReadFileContent(string filePath)
{
var fileContent = File.ReadAllText(filePath);
return fileContent;
}
🤖 Prompt
Zmodyfikuj funkcję ReadFileContent(string filePath) w C#, aby obsługiwała wyjątki związane z dostępem do pliku.
Zarządzanie zasobami – pamiętaj o zwalnianiu zasobów
Efektywne zarządzanie zasobami, takimi jak pliki, połączenia sieciowe czy dostęp do baz danych, jest fundamentalne dla utrzymania wydajności aplikacji i uniknięcia wycieków pamięci.
Każdy otwarty zasób systemowy, który nie zostanie prawidłowo zwolniony, może prowadzić do awarii systemu oraz degradacji wydajności.
Przykładowy kod wejściowy (C#):
public void WriteLog(string message)
{
StreamWriter writer = new StreamWriter("log.txt", true);
writer.WriteLine(message);
}
🤖 Prompt
Zrefaktoryzuj funkcję WriteLog(string message) w C# z użyciem using, aby poprawnie zarządzać obiektem StreamWriter.
Praca z asynchronicznością – usprawnij przetwarzanie równoległe
Asynchroniczność jest nieoceniona przy tworzeniu responsywnych aplikacji.
Zwłaszcza przy operacjach o dużym czasie trwania, takich jak:
- pobieranie danych z API,
- operacje plikowe,
- czy zapytania do bazy danych.
Przykładowy kod wejściowy (JavaScript):
function fetchData(url) {
const response = fetch(url);
return response.json();
}
🤖 Prompt
Przekształć funkcję fetchData(url) w JavaScript na wersję asynchroniczną z async/await.
Unikaj „magic numbers” – nadawaj znaczenie wartościom w kodzie
„Magic numbers” to liczby pojawiające się w kodzie bez kontekstu lub wyjaśnienia, co może utrudniać zrozumienie logiki oraz utrzymanie kodu w przyszłości.
Przypisywanie takich wartości do stałych nie tylko poprawia czytelność, ale także pozwala na łatwiejsze zarządzanie i modyfikację tych wartości w całym projekcie.
Kod będzie bardziej zrozumiały dla innych członków zespołu, a wszelkie zmiany w wartościach nie będą wymagać żmudnego przeszukiwania całego projektu.
Przykładowy kod wejściowy (JavaScript):
function calculateFinalPrice(price) {
return price + (price * 0.2);
}
🤖 Prompt
Zrefaktoryzuj funkcję calculateFinalPrice(price), aby zamiast „magic number” 0.2 używała stałej TAX_RATE.
Użycie typów – zadbaj o większą pewność i jakość kodu
Typowanie, szczególnie w językach takich jak C#, znacząco podnosi jakość i stabilność kodu.
Typowanie umożliwia wczesne wykrywanie błędów związanych z niewłaściwym użyciem danych już na etapie kompilacji.
To ogranicza ryzyko wystąpienia błędów w czasie działania aplikacji.
Przykładowy kod wejściowy (C#):
public double CalculateArea(object length, object width)
{
return (double)length * (double)width;
}
🤖 Prompt
Zmień deklaracje parametrów w funkcji CalculateArea na określone typy, aby zwiększyć bezpieczeństwo i uniknąć błędów związanych z rzutowaniem.
Na koniec
W artykule omówiliśmy typowe błędy programistyczne, które łatwo popełnić, a których sztuczna inteligencja skutecznie unika.
Przedstawiliśmy konkretne przykłady oraz prompty, które pomogą Ci ulepszyć kod i zwiększyć jego niezawodność.
Skupiliśmy się na dobrych praktykach, jak testowanie czy organizacja kodu – działaniach, które przekładają się na długoterminową jakość projektów.
Co dalej?
Dołącz do newslettera, by otrzymywać sprawdzone wskazówki i narzędzia przydatne w pracy programisty.