JavaRush /Java блог /Random UA /Кава-брейк #124. Патер проектування Builder. Як працює се...

Кава-брейк #124. Патер проектування Builder. Як працює серіалізація та десеріалізація в Java

Стаття з групи Random UA

Паттерн проектування Builder у Java

Джерело: Medium У цій статті ми дізнаємося, як проектувати та створювати об'єкти для класу, використовуючи патерн проектування Builder . Кава-брейк #124.  Патер проектування Builder.  Як працює серіалізація та десеріалізація в Java - 1

Навіщо нам потрібний патерн проектування Builder?

Паттерн Builder призначений для створення об'єктів з використанням вкладеного загальнодоступного статичного класу, який має ті самі поля даних, що й зовнішній клас. Паттерн Builder створабо для вирішення проблем, які були у патернах проектування Factory та Abstract Factory , коли об'єкт класу містить багато значень полів та/або даних. Перш ніж ми перейдемо до патерну Builder , давайте подивимося, які саме проблеми виникають із патернами Factory та Abstract Factory для сценаріїв, де об'єкт має багато значень полів:
  1. Наявність дуже багатьох аргументів передачі з клієнтської програми до класу Factory може призводити до виникнення помилок, оскільки у більшості випадків тип аргументів тут і той ж, а з боку клієнта важко підтримувати порядок аргументів.

  2. Деякі параметри можуть бути необов'язковими, але в патерні Factory ми змушені надсилати всі параметри, а необов'язкові параметри необхідно надсилати як NULL файли .

  3. Якщо об'єкт "важкий" і зі складною розробкою, всі ці труднощі стануть частиною класів Factory, що часто призводить до плутанини.

Згадані вище проблеми можна вирішити, коли об'єкт має велику кількість параметрів. Для цього потрібно просто надати конструктору необхідні параметри, а потім різні setter -методи для встановлення необов'язкових параметрів. Зверніть увагу, що проблема з цим способом полягає в тому, що стан об'єкта залишиться непослідовним (inconsistent), якщо всі атрибути чітко не встановлені.

Що таке патерн проектування Builder?

Паттерн Builder вирішує проблему з великою кількістю необов'язкових параметрів та непослідовних станів, надаючи спосіб покрокового створення об'єкта. Для цього використовується метод, що фактично повертає остаточний об'єкт.

Як реалізувати патерн проектування Builder Java?

Якщо ми виконаємо наведені нижче кроки, то отримаємо поетапний процес створення об'єкта та його отримання:
  1. Створіть статичний вкладений клас ( static nested class ) як клас Builder , а потім скопіюйте всі поля із зовнішнього класу до класу Builder . Ми повинні дотримуватися угоди про імена, тому якщо назва класу Person , то клас Builder повинен називатися як PersonBuilder .

  2. Клас Builder повинен мати загальнодоступний конструктор з усіма необхідними полями як параметри.

  3. Клас Builder повинен мати методи встановлення необов'язкових параметрів, і він повинен повертати той самий об'єкт Builder після установки необов'язкового поля.

  4. Останнім кроком є ​​надання методу build() у класі Builder , який повертатиме об'єкт, необхідний для клієнтської програми. Для цього нам потрібно мати приватний конструктор в основному класі з класом Builder як аргумент.

Приклад:

Давайте розглянемо приклад, щоб отримати чітке уявлення про патерн проектування Builder .
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();
    }
}
Приклад шаблону Builder : java.lang.StringBuilder і java.lang.StringBuffer використовували шаблон Builder для побудови об'єктів.

Як працює серіалізація та десеріалізація в Java

Джерело: Medium Я перейшов на Java у січні цього року після стажування. До цього я переважно писав на PHP і трохи на JavaScript. Раніше мені не доводилося стикатися із серіалізацією, хоча насправді серіалізація існує і в PHP. Щоправда, Java вона використовується набагато частіше. Сьогодні я познайомлю вас, як працює серіалізація та десеріалізація в Java та розповім про кілька способів їх застосування.

Що таке серіалізація та десеріалізація

Серіалізація — це перетворення об'єкта з класу на послідовність байтів на віртуальній машині Java (JVM) передачі на іншу віртуальну машину Java. Якщо віртуальна машина Java відтворює об'єкт з байтів, цей процес називається десеріалізацією.

Приклад серіалізації та десеріалізації

Серіалізація

Давайте створимо клас, об'єкт якого буде серіалізований:
import java.io.*;

public class Person implements Serializable{

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

public Person(int identity, String nomenclature) {

name = nomenclature;
id = identity;
}
}
Клас Person реалізує Serializable , щоб його об'єкт можна було серіалізувати/десеріалізувати. Клас Person має два поля: ідентифікатор та ім'я, які змінюються від значення за умовчанням під час створення екземпляра класу. У пакет Java.io були імпортовані інтерфейс Serializable та інші класи, які у програмі.
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();
}
}
}
Як ви знаєте, основний метод запускає серіалізацію та виводить повідомлення про успішний результат, інакше друкується повідомлення про помилку. Для серіалізації об'єктів ми використовуємо ObjectOutputStream і метод writeObject .

Десеріалізація

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();
}
}
}
Десеріалізація є зворотною дією по відношенню до серіалізації. Для відновлення об'єкта з послідовності байтів використовується ObjectInputStream і метод readObject . Зауважте, що для забезпечення доступу до полів у класі Person об'єкт наведено до типу даних Person. Об'єкт класу, який реалізує інтерфейс серіалізації, може бути сериализован. Тому будь-який клас, який посилається на клас, що реалізує інтерфейс серіалізації, має сам реалізовувати інтерфейс серіалізації, інакше буде видано виняток. Серіалізація не залежить від платформи, тобто потік байтів, що серіалізується, може десеріалізуватися іншою віртуальною машиною Java. Статичні та перехідні поля не серіалізуються, тому якщо у вас є поле, яке ви не хочете серіалізувати, зробіть його тимчасовим чи статичним. У разі статичного поля воно не серіалізується, тому що статичне поле належить класу, а чи не об'єкту. Через це перехідний стан запобігає серіалізації поля. Серіалізація застосовується в Hibernate, JPA та RMI. Також можна настроїти серіалізацію. Це називається користувальницькою серіалізацією.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ