JavaRush /Blog Java /Random-PL /Przerwa kawowa #124. Wzór projektowy konstruktora. Jak se...

Przerwa kawowa #124. Wzór projektowy konstruktora. Jak serializacja i deserializacja działają w Javie

Opublikowano w grupie Random-PL

Wzorzec projektowy Buildera w Javie

Źródło: Medium W tym artykule dowiemy się, jak projektować i tworzyć obiekty dla klasy przy użyciu wzorca projektowego Builder . Przerwa kawowa #124.  Wzór projektowy konstruktora.  Jak serializacja i deserializacja działają w Javie — 1

Dlaczego potrzebujemy wzorca projektowego Builder?

Wzorzec Builder jest przeznaczony do tworzenia obiektów przy użyciu zagnieżdżonej publicznej klasy statycznej, która ma te same pola danych, co klasa zewnętrzna. Wzorzec Builder został stworzony, aby rozwiązać problemy, które występowały we wzorcach projektowych Factory i Abstract Factory , gdy obiekt klasy zawiera wiele wartości pól i/lub danych. Zanim przejdziemy do wzorca Builder , przyjrzyjmy się dokładnie, jakie problemy pojawiają się w przypadku wzorców Factory i Abstract Factory w scenariuszach, w których obiekt ma wiele wartości pól:
  1. Zbyt wiele argumentów do przekazania z programu klienckiego do klasy Factory może powodować błędy, ponieważ w większości przypadków typ argumentu jest taki sam i trudno jest zachować kolejność argumentów po stronie klienta.

  2. Niektóre parametry mogą być opcjonalne, jednak we wzorcu Factory jesteśmy zmuszeni przesłać wszystkie parametry, a parametry opcjonalne muszą zostać przesłane jako pliki NULL .

  3. Jeśli obiekt jest „ciężki” i ma złożony projekt, wszystkie te trudności staną się częścią klas fabrycznych, co często prowadzi do zamieszania.

Powyższe problemy można rozwiązać, gdy obiekt ma dużą liczbę parametrów. Aby to zrobić, wystarczy podać konstruktorowi wymagane parametry, a następnie różne metody ustawiające , aby ustawić opcjonalne parametry. Należy pamiętać, że problem z tą metodą polega na tym, że stan obiektu pozostanie niespójny , jeśli wszystkie atrybuty nie zostaną wyraźnie ustawione.

Jaki jest wzorzec projektowy Buildera?

Wzorzec Buildera rozwiązuje problem posiadania wielu opcjonalnych parametrów i niespójnych stanów, zapewniając sposób na budowanie obiektu krok po kroku. Używa metody, która faktycznie zwraca obiekt końcowy.

Jak zaimplementować wzorzec projektowy Builder w Javie?

Jeśli wykonamy poniższe kroki, otrzymamy krok po kroku proces tworzenia obiektu i jego uzyskania:
  1. Utwórz statyczną klasę zagnieżdżoną jako klasę Builder , a następnie skopiuj wszystkie pola z klasy zewnętrznej do klasy Builder . Musimy przestrzegać konwencji nazewnictwa, więc jeśli nazwa klasy to Person , to klasa Builder powinna nazywać się PersonBuilder .

  2. Klasa Builder musi mieć konstruktor publiczny ze wszystkimi wymaganymi polami jako parametrami.

  3. Klasa Builder musi mieć metody ustawiania opcjonalnych parametrów i musi zwracać ten sam obiekt Builder po ustawieniu opcjonalnego pola.

  4. Ostatnim krokiem jest udostępnienie w klasie Builder metody build() , która zwróci obiekt potrzebny programowi klienckiemu. Aby to zrobić, musimy mieć prywatnego konstruktora w klasie głównej z klasą Builder jako argumentem.

Przykład:

Spójrzmy na przykład, aby lepiej zrozumieć wzorzec projektowy Buildera .
public class Employee {

    private String name;
    private String company;
    private boolean hasCar;//optional
    private boolean hasBike;//optional

    private Employee(EmployeeBuilder employeeBuilder) {
        name = employeeBuilder.name;
        company = employeeBuilder.company;
        hasCar = employeeBuilder.hasCar;
        hasBike = employeeBuilder.hasBike;
    }

    public String getName() {
        return name;
    }

    public String getCompany() {
        return company;
    }

    public boolean isHasCar() {
        return hasCar;
    }

    public boolean isHasBike() {
        return hasBike;
    }

    public static class EmployeeBuilder {
        private String name;
        private String company;
        private boolean hasCar;//optional
        private boolean hasBike;//optional

        //constructor for required fields
        public EmployeeBuilder(String name, String company) {
            this.name = name;
            this.company = company;
        }

        //setter methods for optional fields
        public EmployeeBuilder setHasCar(boolean hasCar) {
            this.hasCar = hasCar;
            return this;
        }

        public EmployeeBuilder setHasBike(boolean hasBike) {
            this.hasBike = hasBike;
            return this;
        }

        //Build the Employee object
        public Employee build() {
            return new Employee(this);
        }
    }
}

class TestBuilder {
    public static void main(String[] args) {
        //Building the object of Employee thru the build() method provided in EmployeeBuilder class.
        Employee employee = new Employee.EmployeeBuilder("Vikram", "ABC").setHasBike(false).setHasBike(true).build();
    }
}
Przykładowy wzorzec Buildera : java.lang.StringBuilder i java.lang.StringBuffer używały wzorca Builder do budowania obiektów.

Jak serializacja i deserializacja działają w Javie

Źródło: Medium Przerzuciłem się na Javę w styczniu tego roku po odbyciu stażu. Wcześniej pisałem głównie w PHP i trochę JavaScript. Nigdy wcześniej nie spotkałem się z serializacją, chociaż serializacja faktycznie istnieje w PHP. To prawda, że ​​\u200b\u200bw Javie jest używany znacznie częściej. Dziś przedstawię Wam jak działa serializacja i deserializacja w Javie oraz kilka sposobów ich wykorzystania.

Co to jest serializacja i deserializacja

Serializacja to transformacja obiektu z klasy w sekwencję bajtów w wirtualnej maszynie Java (JVM) w celu przesłania do innej wirtualnej maszyny Java. Jeśli wirtualna maszyna Java odtwarza obiekt z bajtów, proces ten nazywa się deserializacją.

Przykład serializacji i deserializacji

Serializacja

Stwórzmy klasę, której obiekt będzie serializowany:
import java.io.*;

public class Person implements Serializable{

int id = 0;
String name = "empty";

public Person(int identity, String nomenclature) {

name = nomenclature;
id = identity;
}
}
Klasa Person implementuje Serializable, dzięki czemu jej obiekt może być serializowany/deserializowany. Klasa Osoba posiada dwa pola: identyfikator i nazwę, które zmieniają wartość domyślną po utworzeniu instancji klasy. Interfejs Serializable oraz inne klasy użyte w programie zostały zaimportowane do pakietu Java.io.
public static void main(String[] args) throws FileNotFoundException, IOException {

String filename = "filename here";
Person person = new Person(1, "John");

// serialization
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));

try {

out.writeObject(person);
System.out.println("Success");
} catch(Exception e) {

System.out.println("Unsuccessful");
} finally {

if(out != null) {

out.close();
}
}
}
Jak wiadomo, metoda główna rozpoczyna serializację i wypisuje komunikat o powodzeniu, w przeciwnym razie drukowany jest komunikat o błędzie. Do serializacji obiektów używamy ObjectOutputStream i metody writeObject .

Deserializacja

public static void main(String[] args) throws FileNotFoundException, IOException {

String filename = "filename here";
Person person = new Person(1, "John");

// Deserialization
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));

try {

Person personObj = (Person)in.readObject();
System.out.println("Person Id is " +personObj.id + " while name is " + personObj.name);
} catch (Exception e) {

e.printStackTrace();
} finally {

if(in != null) {

in.close();
}
}
}
Deserializacja jest odwrotnością serializacji. Aby zrekonstruować obiekt z sekwencji bajtów, użyj ObjectInputStream i metody readObject . Należy pamiętać, że aby zapewnić dostęp do pól w klasie Person , obiekt jest rzutowany na typ danych Person . Obiekt klasy, który nie implementuje interfejsu serializacji, nie może być serializowany. Dlatego każda klasa odwołująca się do klasy implementującej interfejs serializacji musi sama implementować interfejs serializacji, w przeciwnym razie zostanie zgłoszony wyjątek. Serializacja jest niezależna od platformy, co oznacza, że ​​serializowany strumień bajtów może zostać deserializowany przez inną wirtualną maszynę Java. Pola statyczne i przejściowe nie podlegają serializacji, więc jeśli masz pole, którego nie chcesz serializować, uczyń je tymczasowym lub statycznym. W przypadku pola statycznego nie jest ono serializowane, ponieważ pole statyczne należy do klasy, a nie obiektu. Z tego powodu stan przejściowy uniemożliwia serializację pola. Serializacja jest używana w Hibernate, JPA i RMI. Serializację można również dostosować. Nazywa się to serializacją niestandardową.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION