Te błędy dotyczą wszystkich języków programowania, jednak przykłady, które będę pokazywał, będą pisane w C#. Kolejność przedstawiania błędów nie jest ważna, warto skupić się na wszystkich przedstawianych błędach.
Błąd 1. Używanie złych typów
Ten błąd jest dość ważny, a co więcej, bardzo często spotykany. Pamiętaj, że jeżeli tworzysz jakieś modele, to ich właściwości, czy pola powinny być odpowiednich typów. Nie każda właściwość powinna być typu string (z czym się często spotykam). Ten typ powinien przechowywać tylko tekst. Jeżeli używasz liczb, to w zależności od tego, czy wymagasz liczby całkowitej, zmiennoprzecinkowej, czy kwoty, również powinieneś użyć odpowiedniego typu.
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public decimal Salary { get; set; }
public float Height { get; set; }
public float Width { get; set; }
public bool IsDeleted { get; set; }
public string Position { get; set; }
Dla liczb całkowitych może to być w zależności od rozmiaru np. byte, short, int lub long. Dla liczb zmiennoprzecinkowych float lub double. Dla kwot decimal. Dla dat DateTime, a dla wartości logicznych bool. Tak samo, jeżeli używasz komponentów na interfejsie użytkownika, to również dla każdego z nich znajdziesz odpowiedni, w zależności od tego, w jakim frameworku programujesz. To znaczy np. w WPF'ie dla stringów możesz TextBoxa, dla liczb NumerUpDown, dla boola CheckBoxa, a dla dat DateTimePicker.
Błąd 2. Słabe formatowanie
Z tym zawsze jest problem na początku. Oczywiście nie ma w tym nic dziwnego, formatowanie może być na początku nieintuicyjne, ale z czasem, jeżeli będziesz więcej praktykował, przeglądał kod innych programistów, to na pewno łatwiej Ci będzie stosować dobre formatowanie. Zobacz na kod, który przygotowałem.
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
var employee = new Employee( "Jan Kowalski" );
employee.Position = "Młodszy Programista C#" ;
employee.Work();
Console.ReadLine();
}
}
}
W C# na szczęście dzięki skrótowi CTRL+K+D możesz od razu poprawić formatowanie w liniach. Wtedy kod będzie wyglądał w ten sposób:
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
var employee = new Employee("Jan Kowalski");
employee.Position = "Młodszy Programista C#";
employee.Work();
Console.ReadLine();
}
}
}
Pamiętaj też, żeby nie stosować zbyt dużych przerw pomiędzy liniami, ponieważ również zmniejsza to czytelność kodu. Więcej niż jedna linia odstępu nie jest nigdy potrzebna. Nasz kod może wyglądać w ten sposób:
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
var employee = new Employee("Jan Kowalski");
employee.Position = "Młodszy Programista C#";
employee.Work();
Console.ReadLine();
}
}
}
Zauważ, że teraz ten kod jest dużo bardziej czytelny.
Błąd 3. Złe nazewnictwo zmiennych / metod / klas
Tutaj też ważne jest, żeby trzymać się zawsze tych samych zasad, oczywiście najlepiej zgodnych z przyjętymi konwencjami. Zobacz na ten przykład:
using System;
namespace App
{
public class Employee
{
private string _firstName;
private string lastName;
private DateTime date_of_birth;
public Employee(string name)
{
_firstName = name;
}
public int Id { get; set; }
public string firstName { get; set; }
public string Last_Name { get; set; }
public DateTime DateOfBirth { get; set; }
public decimal salary { get; set; }
public float Height { get; set; }
public float width { get; set; }
public bool ISDELETED { get; set; }
public string Position { get; set; }
public void Work()
{
//
}
public void setname()
{
//
}
}
}
Zauważ, że tutaj mamy 3 pola i w każdym z nich programista stosuje inne nazewnictwo. Raz stosuje nazewnictwo camelCase, raz camelCase z podkreśleniem, innym razem oddziela wyrazy podkreślnikami. Przede wszystkim powinniśmy się trzymać zawsze tych samych ustalonych zasad w jednym projekcie. Do pól zazwyczaj stosuje się podkreślenie plus camelCase.
private string _firstName;
private string _lastName;
private DateTime _dateOfBirth;
Jeżeli chodzi o właściwości, to tutaj stosujemy nazewnictwo PascalCase.
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public decimal Salary { get; set; }
public float Height { get; set; }
public float Width { get; set; }
public bool IsDeleted { get; set; }
public string Position { get; set; }
Tak samo dla metod, w C# stosujemy PascalCase.
public void Work()
{
//
}
public void SetName()
{
//
}
Ponadto, co do samych nazw, to powinny one być samo opisujące, oczywiście nie możemy tutaj przesadzać z długości nazw zmiennych, metod, czy klas, ale pamiętaj, żeby nazwy były w miarę krótkie, ale konkretne i od razu mówiły jakie informacje przechowują. Jak widzisz w przykładzie poniżej nazwa zmiennej "a" nic nam nie mówi:
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
var a = new Employee("Jan Kowalski");
a.Position = "Młodszy Programista C#";
a.Work();
Console.ReadLine();
}
}
}
Tutaj w zależności od sytuacji powinniśmy ją odpowiednio nazwać. Załóżmy, że w naszym przypadku będzie to po prostu employee. Oczywiście nie musi to być taka sama nazwa jak nazwa klasy. Akurat w naszym przypadku tak mamy, ponieważ nie znamy tutaj całego kontekstu.
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
var employee = new Employee("Jan Kowalski");
employee.Position = "Młodszy Programista C#";
employee.Work();
Console.ReadLine();
}
}
}
W każdym razie takie nazwy jak "a" czy "a" z jakąś liczbą np. "a1" są najgorsze. Nie wiadomo w takich sytuacjach co oznaczają i zmniejszają czytelność kodu. Pamiętaj, żeby nadawać odpowiednie nazwy, dzięki czemu ten kod będzie również bardziej czytelny nie tylko dla Ciebie, ale również dla innych programistów.
Błąd 4. Nadmiarowe komentarze
O ile w projektach, na których się uczysz śmiało możesz dodawać komentarze. Dzięki nim łatwiej będzie Ci zrozumieć ten kod, jeżeli będziesz chciał do niego w przyszłości wrócić. To jednak w kodzie powiedzmy produkcyjnym nie powinno się stosować zbyt dużo komentarzy.
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
//tworzenie nowego pracownika
var employee = new Employee("Jan Kowalski");
//ustawiania jego stanowiska
employee.Position = "Młodszy Programista C#";
//wywołanie metody pracuj
employee.Work();
Console.ReadLine();
}
}
}
Zobacz na nasz kod. Przez takie komentarze kod, zamiast stawać się bardziej czytelny, staje się tak naprawdę mniej przejrzysty. Jestem zwolennikiem jak najmniejszej ilości komentarzy w takim kodzie. Wychodzę z założenia, że kod powinien być samo opisujący. Jeżeli będziesz stosował odpowiednie nazewnictwo klas, metod, czy zmiennych, to faktycznie taki będzie. Nie będziesz potrzebował dodawać dodatkowych komentarzy. Jeżeli umieszczam komentarze w kodzie, to tylko w sytuacjach, gdy jakiś kod może nie zostać zrozumiany z różnych przyczyn przez innych programistów, lub przeze mnie w przyszłości. Czyli są to jakieś nieoczywiste rozwiązania, które musiały zostać zaimplementowane w danym przypadku. Także kod powyżej jak najbardziej może wyglądać w ten sposób:
using System;
namespace App
{
class Program
{
static void Main(string[] args)
{
var employee = new Employee("Jan Kowalski");
employee.Position = "Młodszy Programista C#";
employee.Work();
Console.ReadLine();
}
}
}
Mimo braku komentarzy jest on teraz bardziej czytelny.
Błąd 5. Duże metody / klasy
Początkujący programiści lubią tworzyć mniej klas, ale za to bardziej obszernych. Tak samo, jeżeli chodzi o metody. Niestety jest to dość dużo błąd, przez co Twoja aplikacje staje się mało czytelna. Jeżeli później potrzebujesz znaleźć jakiś fragment kodu, to wymaga to od Ciebie bardzo dużo czasu. Musisz pamiętać, że programiści częściej czytają kod niż piszą. W związku z tym trzeba zadbać o komfort czytania tego kodu. Jeżeli stworzysz tzw. kilkutysięcznika, czyli klasę, która ma kilka tysięcy linii, to znalezienie później danego fragmentu kodu jest bardzo czasochłonne. Podobnie z metodami. Powinny one mieć najwyżej kilka, maksymalnie kilkanaście linii, ale nie więcej. Zamiast tworzyć ogromne klasy i metody twórz więcej mniejszych, odpowiednio nazwanych zarówno klas, jak i metod.
Błąd 6. Duplikacje kodu
Czyli tworzenie tego samego kodu w kilku miejscach w naszej aplikacji. Pamiętaj, że jeżeli masz taki sam kod w kilku miejscach, to w przypadku, gdy będziesz musiał dokonać jakiejś modyfikacji, czy poprawić kod, to będziesz musiał te zmiany wprowadzać we wszystkich miejscach. Dużo lepiej wyodrębnić wspólny kod na przykład do osobnej klasy i użyć w kilku miejscach. W zależności od sytuacji możesz także skorzystać z dziedziczenia.
Błąd 7. Nie pisanie reużywalnego kodu
Pamiętaj, że programowanie często składa się z podobnych funkcjonalności. Jeżeli potrzebujesz napisać klasę do szyfrowania danych, to możesz stworzyć ją w osobnej dll'ce i używać w różnych projektach. Dzięki temu w przyszłości możesz zaoszczędzić sporo czasu.
Błąd 8. Spaghetti code
Spaghetti code, czyli kod trudny do zrozumienia, który wygląda jak takie spaghetti. W różnych miejscach są odwołania do różnych klas. Raz np. operacje na bazie danych są w modelu, raz w repozytorium, jeszcze w innych przypadku w kontrolerze, albo nawet w widoku. Brakuje podziału na warstwy i ciężko cokolwiek w takim kodzie znaleźć. Zmiana kodu w jednym miejscu powoduje kolejne błędy w innych. Aby unikać takiego kodu, musisz zastosować odpowiednią architekturę w twojej aplikacji i co ważne trzymać się dobrych wzorców.
Błąd 9. Zła obsługa wyjątków
W miejscach podatnych na błędy koniecznie musisz je odpowiednio obsłużyć. Najlepiej do tego użyj konstrukcji try catch.
public interface ILogger
{
public void Error(string message, Exception exception);
}
public ILogger Logger { get; set; }
public void Work()
{
try
{
//logika podatna na błąd
}
catch (Exception ex)
{
Logger.Error("dodatkowe-informacje-o-błędzie", ex);
throw;
}
}
Zobacz na nasz przykład. Jak widzisz mamy tutaj nasze wywołanie w try catchu, dzięki czemu nasza aplikacji mimo ewentualnego nieoczekiwanego wyjątku będzie dalej działać prawidłowo. Co ważne nie możesz zostawiać pustego catcha i w ten sposób tłumić błędów, ale warto zapisać informacje o ewentualnym błędzie np. do pliku. Dzięki czemu łatwiej później będzie Ci zdiagnozować co tak naprawdę poszło nie tak. Dodatkowo możesz również zaimplementować wychwytywanie wszystkich nieobsłużonych wyjątków w całej aplikacji i w odpowiedni sposób obsłużyć. W każdym frameworku taka implementacja wygląda trochę inaczej, ale zazwyczaj wymaga to tylko napisania kilku linii kodu.
Błąd 10. Próba implementacji wszystkiego od zera
Sam popełniałem ten błąd na początku, gdy zaczynałem naukę programowania. Gdy rozwijasz już aplikacje biznesowe, to nie warto wszystkiego implementować od zera, jeżeli istnieją już inne darmowe rozwiązanie, biblioteki, których możesz użyć. Jeżeli potrzebujesz zapisywać dane do pliku, to nie warto pisać własnej biblioteki, która to będzie robić. Lepiej skorzystać już z istniejących rozwiązań takich jak nlog, serilog, czy log4net. Każde to rozwiązanie będzie lepsze od pisania własnej biblioteki od zera. Takie pisanie od zera może być tylko przydatne w jednym przypadku, gdy piszesz projekt w celu rozwijania swoich umiejętności programowania. Natomiast w aplikacjach, które już piszesz dla swoich klientów nie marnuj na to swojego czasu. Nie ma co odkrywać koła na nowo. Skoro biblioteki są przetestowane i udostępniane, to śmiało możemy z nich korzystać.
Błąd 11. Brak testów jednostkowych
Zastanawiałem się, czy ten punkt również tutaj poruszyć, ponieważ brak pisania testów jednostkowych, to nie tylko błąd początkujących programistów, ale również czasem programistów z większym stażem. Warto już od samego początku wiedzieć, czym są i dlaczego piszemy takie testy. Dzięki nim piszemy kod lepszej jakości i posiada on mniej ewentualnych błędów. A to zawsze jest bardzo ważne dla naszych klientów. Ponadto dzięki nim łatwiejsze jest przeprowadzenie refaktoryzacji kodu. Kod musi być również lepszej jakości, musimy się skupić na dobrych wzorcach, łatwiejsze jest utrzymywanie kodu, a także mamy od razu dokumentacje kodu, który tworzymy.
Błąd 12. Brak walidacji danych wprowadzanych przez użytkownika
Nigdy nie możesz ufać użytkownikowi i powinieneś zabezpieczać się na różne sposoby w miejscach, gdzie pobierasz od niego dane. Zawsze najpierw zweryfikuj, czy to, co podał użytkownik jest odpowiednie, a dopiero następnie wykonuj operacje.
Błąd 13. Nie skupianie się na użytkowniku końcowym
Pisząc aplikacje, warto postawić się w butach użytkownika końcowego, który będzie używał Twojej aplikację. Staraj się jak najbardziej ułatwiać mu korzystanie z tej aplikacji. W zależności od tego, jaką aplikacje piszesz, użytkownicy mogą z niej korzystać nawet kilka godzin dziennie i warto, żeby był to dobrze spędzony czas. Warto dowiedzieć się jak użytkownicy korzystają z aplikacji, wysłuchać ich opinii i ciągle ją ulepszać. Dlatego skup się również na interfejsie użytkownika i tzw. UX, czyli User Experience.
Błąd 14. Zakładanie że jeżeli coś działa, to jest dobre
Jeżeli kopiujesz jakiś kod i chcesz go użyć w swojej aplikacji, to staraj się go zawsze dokładnie przeanalizować linijka po linijce. Nierzadko zdarza się tak, że rozwiązania, które proponują inne osoby, mimo tego, że są plusowane, co prawda mogą działać, ale zdarza się także, że zawierają bugi. Także jak najbardziej możesz sugerować się rozwiązaniami innych, ale zawsze mimo wszystko ten kod analizuj. Tak, żeby zabezpieczyć się przed ewentualnymi błędami w swojej aplikacji. To, że jakiś kod działa, nie zawsze oznacza, że jest dobry, nie zawiera jakichś bugów i jest najbardziej optymalny.
Błąd 15. Nieznajomość podstaw
Staraj się także bardzo dobrze poznać podstawy. Warto wiedzieć, czym są klasy statyczne, abstrakcyjne, czym jest typ referencyjny i wartościowy, czym jest polimorfizm, dziedziczenie, abstrakcja, hermetyzacja, kompozycja, konstruktory, delegaty, zdarzenia, stałe i wiele innych podstawowych zagadnień. Te podstawy będą Ci towarzyszyć w całej Twojej programistycznej karierze, dlatego warto poznać je dobrze, by nie popełniać jakichś podstawowych błędów.
Błąd 16. Nieznajomość zasad czystego kodu
Spróbuj również skupić się na zasadach czystego kodu, dzięki temu Twój kod będzie dobrej jakości. Łatwiej będzie Ci w przyszłości rozwijać aplikacje. Warto wiedzieć czym jest SOLID i stosować się do jego podstawowych założeń. Jasne, że nie jest to wiedza, którą musisz poznać na samym początku, ale po kilku miesiącach nauki, warto już o tym zacząć myśleć. Dobrze poznać popularne wzorce projektowe i zawsze trzymać się dobrych zasad.
PODSUMOWANIE
Tak wygląda moim zdaniem lista 16 najbardziej popularnych błędów początkujących programistów. Między innymi na wszystkie te błędy staram się zwracać uwagę uczestnikom mojego szkolenia Zostań Programistą .NET, w którym pokazuje uczestnikom całą programistyczną drogę od podstaw, aż do pracy na stanowisku programista C#/.NET. Jeżeli interesuje Cię nauka programowania pod moim okiem, to również zapraszam Cię do dołączenia. Link do zapisów: ZostanProgramistaDotNet.pl.
To wszystko na dzisiaj, do zobaczenia w kolejnym artykule.
Poprzedni artykuł - Jak Szybko Przebranżowić Się Na Programistę z Innego Zawodu?.
Następny artykuł - Typ Wartościowy i Typ Referencyjny w C#.