1. Obiekty i klasy

Dzisiaj dowiesz się trochę o tym, jak działa typowy program Java. I ważna wiadomość: każdy program Java składa się z klas i obiektów.

Czym są klasy, już wiesz, ale czym są obiekty?

Zacznę od analogii. Wyobraź sobie, że chcesz zbudować mały statek. Najpierw musisz wykonać rysunek, a następnie przekazać go do fabryki, w której statek zostanie zmontowany zgodnie z tym rysunkiem. Albo dziesięć. Tak, ogólnie tyle statków, ile chcesz. Dziesiątki identycznych statków buduje się według jednego schematu, to jest najważniejsze.

W programowaniu w Javie wszystko jest dokładnie takie samo.

Plany

Programista jest jak projektant. Tylko projektant rysuje plany, a programista Java pisze klasy. Części są następnie tworzone z rysunków i obiektów z klas.

Najpierw piszemy klasy (robimy rysunki), a następnie podczas wykonywania programu maszyna Java tworzy obiekty na podstawie tych klas. Tak jak statki powstają z planów.

Jest tylko jeden rysunek, ale statków może być wiele. Statki są różne, mają różne nazwy, przewożą różne ładunki. Ale są bardzo podobne: wszystkie są statkami o identycznej konstrukcji i mogą wykonywać podobne zadania.

Albo inna analogia...

Mrowisko

Mrowisko jest dobrym przykładem interakcji między obiektami. W najprostszym mrowisku występują trzy klasy mrówek: królowa, wojownicy i mrówki robotnice.

Liczba mrówek z każdej klasy jest inna. Królowa jest jedna na całe mrowisko, są dziesiątki wojowników i setki mrówek robotnic. Trzy klasy i setki obiektów. Mrówki wchodzą ze sobą w interakcję, z tymi samymi mrówkami i mrówkami z innych klas według sztywno określonych reguł.

To jest właśnie doskonały przykład. W typowym programie wszystko jest dokładnie takie samo. Istnieje główny obiekt, który tworzy obiekty wszystkich innych klas. Obiekty zaczynają wchodzić w interakcje ze sobą i ze „światem zewnętrznym” programu. Wewnątrz tych obiektów ich zachowanie jest zakodowane na stałe.

Te dwa wyjaśnienia to dwie strony tej samej monety. Prawda leży pośrodku. Pierwszy przykład (dotyczący schematu i statków) pokazuje związek między klasą a obiektami tej klasy. Analogia jest bardzo mocna. Drugi przykład (o mrowisku) pokazuje związek między obiektami, które istnieją podczas działania programu, a zapisanymi klasami.

Najpierw musisz napisać klasy dla wszystkich obiektów, które istnieją w programie, a następnie opisać ich interakcje. Tak, jest, ale jest to łatwiejsze niż się wydaje.

W Javie wszystkie jednostki są obiektami podczas działania programu, a pisanie programu ogranicza się do opisywania różnych sposobów, w jakie obiekty mogą wchodzić w interakcje. Obiekty po prostu wywołują nawzajem swoje metody i przekazują im wymagane dane.

Dokumentacja

Skąd wiesz, jakie dane przekazać metodom? Wszystko zostało już dla Ciebie pomyślane.

Zazwyczaj każda klasa ma opis, który mówi, do czego została stworzona. Ponadto każda metoda publiczna ma zwykle opis: co robi i jakie dane należy do niej przekazać.

Aby używać klasy, musisz ogólnie wiedzieć, co ona robi. Musisz także dokładnie wiedzieć, co robi każda z jego metod. I wcale nie trzeba wiedzieć, jak to robi. Taka magiczna różdżka.

Spójrzmy na kod - kopiowanie pliku:

Kopiowanie c:\data.txt do c:\result.txt
package com.codegym.lesson2;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy
{
   public static void main(String[] args) throws IOException
   {
      FileInputStream fileInputStream = new FileInputStream("c:\\data.txt");
      FileOutputStream fileOutputStream = new FileOutputStream("c:\\result.txt");

      while (fileInputStream.available() > 0)
      {
         int data = fileInputStream.read();
         fileOutputStream.write(data);
      }

      fileInputStream.close();
      fileOutputStream.close();
   }
}

Jeśli przeczytasz ten kod linia po linii, możesz odgadnąć, co robi w ogólnych warunkach. Chociaż wymaga to doświadczenia i praktyki. Więc po pewnym czasie ten kod wyda ci się znajomy i zrozumiały.


2. Projekt programu

Projektowanie oprogramowania to sztuka. Jest to jednocześnie proste i trudne. Po prostu dlatego, że nie ma ścisłych przepisów: wszystko, co nie jest zabronione, jest dozwolone. Cóż, jest to również trudne z tego powodu: istnieje wiele sposobów na zrobienie czegoś i nie jest łatwo znaleźć najlepszy.

Projektowanie programu przypomina pisanie książki. Z jednej strony po prostu piszesz litery, słowa, zdania. A z drugiej strony ważna jest fabuła, charaktery bohaterów, wewnętrzne sprzeczności, konflikty, styl narracji, intryga itp.

Najważniejsze jest, aby zrozumieć, dla kogo piszesz kod. I piszesz kod dla innych programistów.

Rozwój każdego produktu polega na wprowadzaniu zmian: tu dodanych, tam usuniętych, tu przerobionych. I tak w małych iteracjach rodzą się duże, ogromne i gigantyczne projekty.

Głównym wymaganiem dla kodu jest to, aby był zrozumiały dla innych programistów. Niepoprawny, ale zrozumiały kod można poprawić. Poprawnego i niezrozumiałego kodu nie da się poprawić.  Zostanie tylko wyrzucony.

Jak więc pisać dobry i zrozumiały kod?

Aby to zrobić, musisz zrobić trzy rzeczy:

  • Pisanie dobrego i zrozumiałego kodu wewnątrz metod to najłatwiejsza rzecz.
  • Zdecyduj, jakie podmioty powinny znaleźć się w programie
  • Poprawnie podziel program na logiczne części

Co kryje się za tymi koncepcjami?

Pisz dobry kod wewnątrz metod

Jeśli masz co najmniej podstawowy poziom języka angielskiego, być może zauważyłeś, jak łatwo czasami odczytać kod: jak zdania w języku angielskim:

  • class Cat extends Pet– klasa Cat rozszerza klasę Pet
  • while(stream.ready())- gdy strumień jest gotowy...
  • if (a<b) return a; else return b– jeśli аmniej b, wróć а, w przeciwnym razie wróć b.

To jest zrobione celowo. Java jest jednym z niewielu języków, w których łatwo napisać samodokumentujący się kod: kod zrozumiały bez komentarzy. W dobrym kodzie Java wiele metod brzmi jak zdania w języku angielskim.

Twoim zadaniem podczas pisania kodu jest również uczynienie go tak prostym i zwięzłym, jak to tylko możliwe. Pomyśl tylko, jak łatwy będzie do odczytania Twój kod, a zaczniesz zmierzać we właściwym kierunku.

W Javie zwyczajowo pisze się kod, który jest łatwy do odczytania. Pożądane jest, aby każda metoda mieściła się w całości na ekranie (długość metody to 20-30 linii). Jest to norma dla całej społeczności Java. Jeśli kod można poprawić, należy go poprawić.

Najlepszym sposobem na nauczenie się pisania dobrego kodu jest ciągła praktyka. Pisz dużo kodu, studiuj kod innych osób, poproś bardziej doświadczonych kolegów o przejrzenie twojego kodu.

I pamiętaj, że w momencie, gdy powiesz sobie „i tak będzie”, Twój rozwój się zatrzyma.

Zdecyduj, jakie podmioty powinny znaleźć się w programie

Musisz napisać kod zrozumiały dla innych programistów. Jeśli 9 na 10 programistów podczas projektowania programu tworzy klasy A, B i C, to ty powinieneś również stworzyć w swoim programie klasy A, B i C. Musisz pisać kod zrozumiały dla innych.

Świetny, działający, szybki, niestandardowy kod to zły kod.

Musisz przestudiować projekty innych ludzi: to najlepszy, najszybszy i najłatwiejszy sposób na poznanie całej mądrości gromadzonej w branży IT od dziesięcioleci.

A tak przy okazji, masz już pod ręką świetny, popularny, dobrze udokumentowany projekt - Java SDK . Zacznij od tego.

Deasemblować klasy i struktury klas. Zastanów się, dlaczego niektóre metody są statyczne, a inne nie. Dlaczego metody mają takie parametry, a nie inne. Dlaczego właśnie takie metody, dlaczego klasy nazywają się dokładnie w taki sposób i znajdują się w takich paczkach.

Kiedy zaczniesz rozumieć odpowiedzi na wszystkie te pytania, będziesz w stanie pisać kod zrozumiały dla innych.

Chcę jednak ostrzec przed parsowaniem kodu w metodach Java SDK. Kod wielu metod został przepisany w celu zmaksymalizowania szybkości pracy - dużym pytaniem jest jego czytelność.

Poprawnie podziel program na logiczne części

Każdy program jest zwykle podzielony na części lub moduły. Każda część odpowiada za swój własny aspekt programu.

Tutaj komputer ma jednostkę systemową, monitor, klawiatury, a to wszystko oddzielne, mało zależne części. Ponadto ich interakcja jest ustandaryzowana: USB, HDMI itp. Ale jeśli wylejesz kawę na klawiaturę, możesz po prostu umyć ją pod kranem, wysuszyć i użyć ponownie.

Ale laptop jest przykładem architektury monolitycznej: części logiczne wydają się tam być, ale są one znacznie bardziej zintegrowane. Na MacBooku Pro, aby wyczyścić klawiaturę, musisz zdemontować połowę laptopa. A kawa rozlana na laptopie to powód do zamówienia nowego. Tylko nie kawa.


3. Stwórz własne zajęcia

Lecz odkąd dopiero uczysz się kodować, musisz zacząć od małego - naucz się tworzyć własne klasy.

Oczywiście już je stworzyłeś, ale musisz nauczyć się rozumieć, jakie klasy powinny być w programie, jak powinny się nazywać, jakie powinny mieć metody. I jak powinni ze sobą współdziałać.

Lista podmiotów

Jeśli nie wiesz od czego zacząć, zacznij od początku.

Na samym początku projektowania programu można po prostu wypisać na kartce listę podmiotów (obiektów), które powinny znaleźć się w programie. A potem zaprogramuj je zgodnie z tą zasadą: każdy byt to osobna klasa.

Przykład

Powiedzmy, że chcesz napisać grę w szachy. Będziesz potrzebował następujących elementów: szachownica i 6 rodzajów figur. Pionki poruszają się inaczej, mają różne wartości – logiczne jest, że są to odrębne klasy. I generalnie na samym początku im więcej zajęć tym lepiej.

Spotkać początkującego programistę, który napisałby dziesięć zamiast dwóch klas, to rzadkość. Tutaj zamiast dziesięciu napisz dwa, a nawet jeden - to jest to, co uwielbiają początkujący. Więc więcej zajęć Panowie programiści. A Twój kod stanie się bardziej zrozumiały dla wszystkich, może z wyjątkiem Ciebie 😛

Szachy

Powiedzmy, że decydujemy się napisać zajęcia z szachów: jak miałyby wyglądać te zajęcia?

Czy szachownica to tylko tablica 8 na 8? Lepiej zrobić dla niego oddzielną klasę, która przechowuje odwołanie do tablicy wewnątrz. Wtedy do klasy „szachownica” można dodać wiele przydatnych metod, które np. sprawdzą czy komórka jest pusta lub zajęta

Generalnie na początku zawsze można kierować się zasadą: Program ma różne Podmioty, a Podmiot ma typ. Ten typ to klasa.


4. Zmienne statyczne i metody

Nie zapomnij również użyć zmiennych statycznych i metod. Jeśli masz jedną figurę szachową wchodzącą w interakcję z inną na szachownicy, musisz mieć w swoim kodzie metodę, która przekazuje odniesienia do pierwszej figury, drugiej figury i szachownicy.

Aby nie przekazywać stale odwołań do obiektów, które „zawsze istnieją”, są one zwykle zmiennymi statycznymi i można uzyskać do nich dostęp z dowolnego miejsca w programie.

Na przykład tak:

Kod Notatka
public class ChessBoard
{
   public static ChessBoard board = new ChessBoard();
   public ChessItem[][] cells = new ChessItem[8][8];
   ...
}

public class Game
{
   public static void main(String[] args)
   {
      var board = ChessBoard.board;
      board.cells[0][3] = new King(Color.WHITE);
      board.cells[0][4] = new Queen(Color.WHITE);
      ...
   }
}


Odwołanie do pojedynczego obiektu typu ChessBoard.
Tablica 2D 8×8, a nie zmienna statyczna.








Dodawanie figurek do planszy.

Cóż, albo zamiast zmiennej statycznej możesz zrobić metodę, która zwraca pojedynczy obiekt. Na przykład tak:

public class ChessBoard
{
   private static ChessBoard board = new ChessBoard();
   public static ChessBoard getBoard()
   {
      return board;
   }

   public ChessItem[][] cells = new ChessItem[8][8];
   ...
}

public class Game
{
   public static void main(String[] args)
   {
      var board = ChessBoard.getBoard();
      board.cells[0][3] = new King(Color.WHITE);
      board.cells[0][4] = new Queen(Color.WHITE);
      ...
   }
}