User Эллеонора Керри
Эллеонора Керри
41 уровень

Кофе-брейк #124. Паттерн проектирования Builder. Как работает сериализация и десериализация в Java

Статья из группы Random

Паттерн проектирования 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. Сериализацию также можно настроить. Это называется пользовательской сериализацией.
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ