Jesteś tutaj
Główna > BlogV1 > C#, .NET, OOP… czyli jak programować ładnie i zgrabnie?

C#, .NET, OOP… czyli jak programować ładnie i zgrabnie?

Skoro czytasz ten artykuł to mogę śmiało założyć, że już nie możesz doczekać się kiedy stworzysz swój pierwszy iTunes czy napiszesz swoje pierwsze Call of Juarez. Bardzo dobrze, ponieważ już niedługo faktycznie stworzymy coś co przydać Ci się będzie mogło w życiu codziennym. Do tego jednak zaczniemy czynić poważne przygotowania już teraz! W dzisiejszym artykule zajmiemy się rozwinięciem wiedzy oraz umiejętności z poprzedniego. Zrobimy bardzo podobny projekt, jednak teraz delikatnie zastosujemy nowoczesne technologie dla lepszej i dużo bardziej eleganckiej implementacji. Do dzieła!

[Cykl – Baza]

Technologia

Cały czas pozostajemy w środowisku Visual Studio. Tym razem jednak rezygnujemy z C++ i przesiadamy się na C# – obiektowy język stworzony przez Microsoft. Nie musisz się jednak bać tej zmiany – korzystając z niego cały czas pozostajemy w rodzinie języków C, jestem przekonany że bez problemu go zrozumiesz i już za chwilę zaczniesz w pełni wykorzystywać możliwości jakie Ci daje ;). Korzystanie z C# to jednak nie koniec zmian – nieśmiało rozpoczniemy dzisiaj przygodę z .NET – technologią stworzoną przez Microsoft. Nieśmiało ponieważ dziś wykorzystamy zaledwie kilka fragmentów z przepastnych zbiorów naszych kolegów zza oceanu. Nie musisz się jednak martwić – już za niedługo (wraz z rozpoczęciem nowego cyklu!) odważniej wejdziemy w to co oferują nam Amerykanie i będziemy czerpać do woli. Zróbmy jednak krótki wstęp do C#. Zasadniczo jest to język bliźniaczo podobny do znanego Ci już doskonale C++. Jest jednak kilka istotnych zmian. Wymieńmy te elementy języka które nas będą dzisiaj interesować.

Wskaźniki do kosza

Koniec z niskopoziomowym zarządzaniem pamięcią, wskaźniki w C#… nie istnieją! A konkretnie istnieją w trybie unsafe, jednak nie są tak naprawdę niezbędne dla zaawansowanego programowania w tym języku. To dla nas dobra wiadomość, oczywiście o ile chcemy się skupić na stworzeniu złożonych aplikacji bez zastanawiania jak je niskopoziomowo optymalizować. Odpada nam jednak element sprawiający nierzadko bardzo duże problemy

Pętla Foreach

Pętla foreach jest – jak można się domyśleć – rozwinięciem pętli for. Dzięki niej możemy w bardzo łatwy sposób przejść się po kolekcji (np. tablicy) nawet nie znając jej długości.

Na początku stworzyłem tablicę (tak się to robi w C#;) ) a potem wyświetliłem na ekranie wszystkie jej elementy za pomocą pętli foreach. Co ważne! Pętla ta jest read-only, służy tylko do odczytu i nie można napisać np. „element = 5”. W powyższym przykładzie pominąłem zupełnie wypełnienie tablicy (można zrobić to używając np. tradycyjnej pętli for w klasycznym wydaniu – nie różni się ona niczym od znanej z C++).

Właściwości (properties)

Pamiętasz czym są getery i setery? No! To teraz śmiało możesz zapomnieć… No dobrze, troszkę przesadziłem, jednak C# wprowadza zupełnie nowy element (poza polami i metodami) nazwany properties (właściwości). W skrócie jest to coś między metodą a polem, co w zręczny sposób zastępuje getery i setery. Co prawda zastosowań ma mnóstwo, jednak o tym przekonasz się w następnych artykułach. Na ten moment spójrzmy na następujący kod.

I następnie ten – napisany w funkcji main():

Najpierw stworzyliśmy prywatną zmienną _name, a następnie właściwość Name. W bloku właściwości ustalamy zasady działania get oraz set. W tym przypadku daliśmy prostą, bez żadnych obostrzeń (moglibyśmy np. wewnątrz bloku get wstawić jakiegoś if’a i dzięki niemu dodać pewne warunki które obowiązywałyby przy próbie odczytu). Następnie (w main) widzimy jak z właściwości skorzystać. Tak! Jest to najprostsza na świecie operacja i wygląda dokładnie tak, jakbyśmy używali zwykłego pola. Oczywiście nie możemy zrobić tego z _name, ponieważ to pole prywatne. Właściwości łączą więc możliwości obostrzeń znane z metod Get() i Set() oraz prostotę użycia zwykłych pól. Fajne? Fajne.

To jednak nie koniec! W powyższym przypadku mamy bardzo prostą, zupełnie niezłożoną problematykę. W takiej sytuacji możemy jeszcze bardziej uprościć kod i wyglądałby on następująco.

W tym przypadku nie musimy nawet tworzyć prywatnego pola – właściwość jest samowystarczalna! Jeśli np. nie chcielibyśmy dawać możliwości odczytu, dodajemy przed ‘get’ słówko ‘private’. Powodzenia w zabawie z właściwościami!



Baza produktów raz jeszcze

W poprzednim artykule stworzyliśmy prostą aplikację ze zbiorem produktów sklepowych i możliwościami prostych operacji na nich (np. dodawanie nowych produktów, obliczanie ogólnej ceny wszystkich itd.). Teraz również zajmiemy się stworzeniem naszego „Shop Base”, jednak wykorzystamy zdobytą przed chwilą wiedzę z zakresu C# oraz bardzo podstawowe dobrodziejstwa technologii .NET. Napiszmy tu jeszcze raz ogólną strukturę aplikacji (nieco zmienioną wobec poprzedniego artykułu).

  • Product- oczywiście najbardziej podstawowa klasa.

Właściwości:

  • int Id
  • string Name
  • Float Price

Metody:

  • WriteProduct()

 

  • Base – baza produktów. Wykorzystamy ją dwukrotnie. Najpierw jako ogólny zbiór a później również jako nas osobisty koszyk.

Pola:

  • List<Product> products – Lista produktów
  • Int id – potrzebne nam do zliczania ile już w bazie było produktów generalnie.

Właściwości:

  • String Name

Metody:

  • AddProduct()
  • RemoveProduct()
  • WriteProducts()
  • CalculateProducts()
  • FindProduct()

Zabierzmy się więc za implementację! Jestem przekonany że gdy po wszystkim spojrzysz na swoją aplikację z zeszłego tygodnia i obecną nie będziesz mógł uwierzyć. Najpierw zacznijmy od stworzenie klasy Product.

Tak, zgadza się – to cała klasa Product! Szybko licząc mamy… ponad 70 linijek kodu mniej! Na początku tworzymy stosowne właściwości (Ponieważ nie chcemy by produktowi zmieniać później nazwę, ‘set’ ustawiliśmy jako prywatne), następnie przechodzimy do metod. Mamy dwa konstruktory, z których jeden nie ustawia żadnych właściwości i na końcu prościutką metodę WriteProduct która wypisuje na konsole dane odnośnie produktu. Prawda że proste?

Przejdźmy do nieco bardziej zaawansowanej struktury, jaką jest klasa Base

Tu znów mamy oszczędność kodu (choć nie tak dużą jak przy poprzedniej klasie). Więcej jednak miejsca muszę poświęcić na wyjaśnienie. Na początku tworzymy dwa pola zastrzeżone (pamiętasz czym się różni ‘protected’ od ‘private’? Jeśli nie, zachęcam do zerknięcia w poprzedni artykuł😉 ). Najgroźniej wyglądającym jest „products”, które jest Listą. Nie bój się, już wyjaśniam o co chodzi. Listy to kolekcje, pewne zaawansowane zbiory danych które dostajemy w ramach .NET. Spytasz pewnie „Po co? Przecież mamy tablice!”. Zgadza się, jednak listy – w przeciwieństwie do klasycznych tablic – są dynamiczne i nie musisz z góry określać ile mają „slotów”. Po drugie, mają zaimplementowane kilka bardzo sprytnych metod których użycie bardzo ułatwia korzystanie z nich. Jak zobaczysz w kolejnych metodach, dodawanie czy usuwanie elementów listy jest o niebo prostsze niż usunięcie z tablicy. Mimo że mam nadzieję, że ten krótki opis wystarczy Ci w zrozumieniu kodu zachęcam do zgłębienia wiedzy o listach i innych kolekcjach generycznych – również ze względu na pewien brak precyzji którym niestety muszę się posługiwać w tym artykule. Przejdźmy zatem do wspomnianych metod. Poza konstruktorem pierwszą z nich jest AddProduct(), która dodaje do listy produkty. Jak widzisz nie trzeba „bawić” się z wymyślaniem dziwnych kombinacji – wystarczy dać nazwę listy a potem po kropce „Add” i w parametrze obiekt który chcemy wstawić. Czy nie jest to prostsze? W RemoveProduct() używamy pętli foreach którą opisywałem wyżej i metody Remove() którą daje nam lista. Jako że reszta metod budowana jest na podobnej zasadzie, przejdę do omówienia ostatniej. W FindProduct() znów używamy pętli foreach i zwracamy znaleziony obiekt. No tak… a co jeśli nie uda nam się znaleźć obiektu? W takiej sytuacji pętla zakończy swoje działanie (return kończy pętlę i resztę działania metody) i dojdzie do drugiego „return” zwracając tym samym zupełnie nowy obiekt (bez właściwości).

Finalny stan programu
Finalny stan programu

Brawo! Stworzyłeś prostą aplikację do zarządzania produktami w elegancki sposób, korzystając z nowoczesnej technologii. Ze względu na brak miejsca nie zamieszczam tu implementacji funkcji main(). Możesz jednak zajrzeć do materiałów i pobrać cały kod programu. Jeśli masz jakieś pytania lub uwagi jestem cały czas do dyspozycji pod mailem. Pod koniec wypada mi przestrzec przed niezbyt precyzyjnymi stwierdzeniami które padły w tym artykule. Moim zadaniem jest zachęcić Cię do pogłębiania wiedzy. Robię to z przyjemnością, jednak ze względu na specyficzny charakter artykułu czasem to co piszę jest nieprecyzyjne a implementacja niezbyt elegancka. Zwracam na to twoją uwagę i nakłaniam do poszerzania wiedzy i umiejętności poprzez czytanie tutoriali, kodu innych programistów oraz – co najważniejsze – pisanie swoich aplikacji. Jeśli chciałbyś się pochwalić czymś co napisałeś – wyślij mi to na maila. Ja sprawdzę i odpiszę, a jeśli będzie naprawdę dobre – napiszę o tym na swoim blogu;)

Co dalej?

Tym oto artykułem kończymy cykl nazwany „Cyklem-Bazą”. Poznałeś w nim podstawy programowania obiektowego i liznąłeś C# wraz z technologią .NET. Powinieneś jednak potraktować to jako rozgrzewkę przed czymś naprawdę ekscytującym! Już niedługo po czubek głowy zanurzysz się w .NET i zaczniesz tworzyć aplikację użytkową! Czy to znaczy że wszystko co napisaliśmy do tej pory będzie Bezużyteczne? Absolutnie! Cały czas będziemy siedzieć w tej samej tematyce, pomyślimy jednak jak ją rozbudować i nadać temu ładny wygląd. Do zobaczenia za tydzień!

Skoro dotarłeś do końca – zostańmy w kontakcie na dłużej

Jeśli dotarłeś aż tutaj, to znaczy że jesteś człowiekiem innym niż większość. To znaczy, że nie wystarczają Ci skrótowce, że prawdopodobnie wymagasz od siebie nieco więcej niż przeciętnie. Pozostańmy zatem w kontakcie – zapisz się na Newsletter Wolnego Człowieka i pomóż mi tworzyć coraz lepsze treści! Jeśli zdecydujesz się wpisać – obiecuję zero spamu. Raz w tygodniu będziesz dostawał maila z podsumowaniem tego co zrobiłem na blogu.

 

Ja nazywam się Marek Czuma,  a to jest IT-Blog Wolnego Człowieka

piszę do Ciebie prosto z Łodzi

Marek Czuma
Autor Bloga Republikańskiego. Chrześcijanin, Polak, Łodzianin. Wierzy w ludzi i ich możliwości, kocha pomagać innym. Uważa, że człowiek wolny kształtuje siebie poprzez własne wybory oraz pracę. Poza tym fan Wiedźmina i CD Projektu - zarówno na giełdzie, jak i w działaniu.

9 thoughts on “C#, .NET, OOP… czyli jak programować ładnie i zgrabnie?

  1. a co jeśli dwa produkty mają takie, same id? znajdzie pierwszy a co z drugim, czy id może się zmienić, jeśli nazwa się nie zmienia to powinna mięć pole readonly, dlaczego używasz listy zmiast hashset lub dictionary, konwencja mówi że nie stosuje się _ przed nazwą właściwości powinny być pod kontruktorem, słowo product w medotach jest zbedne bo jako parametr podajesz produkt, wiec to oczywiste że do dodajesz produkt( aż brzmi głupio). CalculateProduct jest całkiem mylące, powinno być Coś Ala calculateTotalValue tam gdzie wyszukujesz produkt po id, nazwa powinna konczyć sie na key, id lub at bo tak jest w normalnych kolekcjach. Write ssie powinieneś nadpisać to string

    1. Tak jak podkreślałem, całość jest bardzo uproszczona ; – ) Skierowana dla ludzi, którzy chcą postawić dopiero pierwsze kroki w .NET, dlatego nie ma np mechanizmów nadpisania ToString() (co nie znaczy, że to co napisałeś nie jest sensowne, chociaż stwierdzenie „write ssie” jest mało konkretne:p). Listę stosowałem, bo słownik w tym konkretnym momencie się nie nadaje, to raz. Dwa – to jedna z najpopularniejszych kolekcji i chciałem je nowym osobom zaprezentować (wykorzystywana o niebo częściej niż hashset lub dictionary). Nazwy są żywcem przeniesione z poprzedniego artykułu, ponieważ to zrobienie tego samego w .NET.
      Co do „_nazwa” jako nazwa w argumencie metody – nie spotkałem się nigdy z krytyką tego zjawiska, konwencje zwykle tego nie regulują pozostawiając do uregulowania programistom, bardzo łatwo się odróżnia od reszty kodu, jest wygodne. Oficjalna konwencja microsoftowa tego nie reguluje.
      Oczywiście dziękuję za komentarz! Jeśli chciałbyś napisać bardziej rozbudowaną, „poprawioną” wersję dla naszych czytelników, to zachęcam, podeślij na maila, a ja przejrzę i zamieszczę – oczywiście z podaniem autora;-)

  2. https://msdn.microsoft.com/en-us/library/ms229045(v=vs.110).aspx pisze żeby nie uzywać _ 😉
    No to w poprzednim artykule też nie potrzebnie dodałeś słowo produkt.

    Wcześniej nie zauważyłem że kopiujesz produkt, w metodzie Add, przecież to jakaś masakra. Produkt nie powinien nieć właściwości id, to co zrobiłeś jest tak absurdalne że trudno o logiczne argumenty. Jakim cudem użytkowanik klasy base jest w stanie odleźć, lub usunąć produkt po ID jak go nie zna bo jest private? ma wypisać sobie w konsoli przepisać na na kartke i wywołać metodę remove? tego id się nawet przewidzieć nie da bo jak ktoś będzie konsekwentnie usuwał ze środka i to wyjdzie ser szwajcarski. To że dictionary i hashset są idealne do sytuacji z unikalnym id(po to je wymyślono) i to ze produkt powinien być strukturą przemilczę.

    1. Tak jak już napisałem raz, powtórzę i drugi. Artykuł ma zapoznać z podstawami C# i .NET, jak to już pisałem nawet w treści – uproszczenia są konieczne i rzeczy które normalnie w projekcie byłyby niedopuszczalne, w tym przypadku nie są problemem. Powiem więcej – przeciwnie, problemem mogłoby się stać „ładne” kodowanie ze względu na większy poziom skomplikowania.
      Ale jeśli mam już tłumaczyć konkretnie, to: id produktu jest public. Produkt strukturą? Ciekawe podejście, na szczęście struktur się nie używa, szczególnie nie w C#, a najbardziej szczególnie nie tam gdzie jest choćby ślad hermetyzacji. To czemu stosuję listę już powiedziałem.
      Ale powtórzę – chętnie przyjmę lepszą, napisaną hiperpoprawnie wersję tego samego programu i zamieszczę również w celach edukacyjnych. Ten artykuł będzie wprowadzał w podstawy, zaś ten drugi – w standardy. To jak?

      1. Przemilczałeś każdy punkt nie masz racji, nie odniosłeś się merytorycznie do tego co napisałem i idziesz w zaparte że tak jest dobrze i ja mam Ci coś jeszcze udowadniać?
        To zrobiłeś z tym to już nawet nie jest kwestia prostoty czy skomplikowania, to jest po prostu głupie. Klasy base nie da sie używać.

        Pisałem o id w klasie base, kopiujesz produkt zapisujesz do bazy z ustawiasz mu NOWE id znane tylko klasie base i nikomu innemu id, a jedyną możliwość odnalezienia tego produktu to jest wyszukanie po id, którego nikt nie zna. Gdzie tu jest prostota.

        Nie używa sie? a DateTime, Point itp. czym są? w klasie produkt jest tylko ślad hermetyzacji bo wszystko po za nazwą ma public set; get; wiec nawet z godnie z twoją logiką spełnia warunki na strukturę. Poza tym nawet jeśli użyłeś słowa class, to w cale nie zmienia faktu że jest to struktura. Poza kulawym toStringiem klasa produkt nie ma żadnych metod wiec jest tylko opakowaniem na dane, wiec jest strukturą, to że ją kopiujesz też swiadczy że to struktura. Jest o tym tuzin ksiązek i 10 tuzinów filmików na youtube.

        1. Odnioslem sie, pare razy;-) Nie masz mi nic udowadniac, jesli masz potrzebe podzielenia sie z innymi czytelnikami standardami pisania kodu, to napisz identyczny program napisany wlasnie z zachowaniem tych standardow, opisz czemu powinno sie pisac tak a nie inaczej bo uwazam ze moze to byc mega pozyteczne i nakierowac poczatkujacych programistow na wlasciwa droge, a ja to opublikuje. Jesli to natomiast ma byc pusta krytyka, to polecam zajac sie czyms pozyteczniejszym;-) I jeszcze raz dziekuje za aktywnosc!
          P.s.
          Na przyszlosc prosilbym podpisywac sie imieniem lub imieniem i nazwiskiem
          Pozdrawiam!

  3. Co to za dodatek do WP co tak ladnie koloruje składnie? 😀 Artykuł bardzo wartościowy i oby więcej rzeczy o oop

    1. Dziękuję bardzo;-) A dodatek to Crayon Syntax Highlighter. Polecam, bardzo fajna wtyczka i prosta w użyciu;-)

Comments are closed.

Top