JavaRush /Blogue Java /Random-PT /Pausa para café #124. Padrão de design do construtor. Com...

Pausa para café #124. Padrão de design do construtor. Como funcionam a serialização e a desserialização em Java

Publicado no grupo Random-PT

Padrão de design do construtor em Java

Fonte: Médio Neste artigo, aprenderemos como projetar e criar objetos para uma classe usando o padrão de design Builder . Pausa para café #124.  Padrão de design do construtor.  Como funcionam a serialização e a desserialização em Java - 1

Por que precisamos do padrão de design Builder?

O padrão Builder foi projetado para criar objetos usando uma classe estática pública aninhada que possui os mesmos campos de dados da classe externa. O padrão Builder foi criado para resolver problemas que estavam presentes nos padrões de design Factory e Abstract Factory quando um objeto de classe contém muitos valores de campo e/ou dados. Antes de passarmos para o padrão Builder , vamos ver exatamente quais problemas surgem com os padrões Factory e Abstract Factory para cenários onde um objeto tem muitos valores de campo:
  1. Ter muitos argumentos para passar do programa cliente para a classe Factory pode causar erros porque na maioria das vezes o tipo de argumento é o mesmo e é difícil manter a ordem dos argumentos no lado do cliente.

  2. Alguns parâmetros podem ser opcionais, mas no padrão Factory somos obrigados a enviar todos os parâmetros, e os parâmetros opcionais devem ser enviados como arquivos NULL .

  3. Se o objeto for “pesado” e com design complexo, todas essas dificuldades passarão a fazer parte das aulas de Fábrica, o que muitas vezes leva à confusão.

Os problemas acima podem ser resolvidos quando o objeto possui um grande número de parâmetros. Para fazer isso, você simplesmente precisa fornecer ao construtor os parâmetros necessários e, em seguida, vários métodos setter para definir os parâmetros opcionais. Observe que o problema com este método é que o estado do objeto permanecerá inconsistente , a menos que todos os atributos sejam claramente definidos.

Qual é o padrão de design do Builder?

O padrão Builder resolve o problema de ter muitos parâmetros opcionais e estados inconsistentes, fornecendo uma maneira de construir um objeto passo a passo. Isso usa um método que realmente retorna o objeto final.

Como implementar o padrão de design Builder em Java?

Se seguirmos as etapas abaixo, obteremos o processo passo a passo de criação de um objeto e recuperação dele:
  1. Crie uma classe estática aninhada como a classe Builder e copie todos os campos da classe externa para a classe Builder . Temos que seguir uma convenção de nomenclatura, portanto, se o nome da classe for Person , então a classe Builder deverá ser chamada PersonBuilder .

  2. A classe Builder deve ter um construtor público com todos os campos obrigatórios como parâmetros.

  3. A classe Builder deve ter métodos para definir os parâmetros opcionais e deve retornar o mesmo objeto Builder após definir o campo opcional.

  4. A última etapa é fornecer um método build() na classe Builder , que retornará o objeto necessário ao programa cliente. Para fazer isso precisamos ter um construtor privado na classe principal com a classe Builder como argumento.

Exemplo:

Vejamos um exemplo para obter uma compreensão clara do padrão de design 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();
    }
}
Exemplo de padrão Builder : java.lang.StringBuilder e java.lang.StringBuffer usaram o padrão Builder para construir objetos.

Como funcionam a serialização e a desserialização em Java

Fonte: Medium Mudei para Java em janeiro deste ano após um estágio. Antes disso, eu escrevia principalmente em PHP e um pouco de JavaScript. Eu nunca tinha encontrado serialização antes, embora a serialização realmente exista em PHP. É verdade que em Java é usado com muito mais frequência. Hoje vou apresentar como a serialização e a desserialização funcionam em Java e várias maneiras de usá-las.

O que é serialização e desserialização

Serialização é a transformação de um objeto de uma classe em uma sequência de bytes na Java Virtual Machine (JVM) para transmissão para outra Java Virtual Machine. Se a Java Virtual Machine recriar um objeto a partir de bytes, o processo será chamado de desserialização.

Exemplo de serialização e desserialização

Serialização

Vamos criar uma classe cujo objeto será serializado:
import java.io.*;

public class Person implements Serializable{

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

public Person(int identity, String nomenclature) {

name = nomenclature;
id = identity;
}
}
A classe Person implementa Serializable para que seu objeto possa ser serializado/desserializado. A classe Person possui dois campos: identificador e nome, que mudam do valor padrão quando uma instância da classe é criada. A interface Serializable e demais classes utilizadas no programa foram importadas para o pacote 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();
}
}
}
Como você sabe, o método principal inicia a serialização e imprime uma mensagem de sucesso, caso contrário é impressa uma mensagem de erro. Para serializar objetos usamos ObjectOutputStream e o método writeObject .

Desserialização

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();
}
}
}
A desserialização é o inverso da serialização. Para reconstruir um objeto a partir de uma sequência de bytes, use ObjectInputStream e o método readObject . Observe que para fornecer acesso aos campos da classe Person , o objeto é convertido no tipo de dados Person . Um objeto de classe que não implementa a interface de serialização não pode ser serializado. Portanto, qualquer classe que faça referência a uma classe que implementa uma interface de serialização deve implementar ela própria a interface de serialização, caso contrário, uma exceção será lançada. A serialização é independente de plataforma, o que significa que o fluxo de bytes serializado pode ser desserializado por outra Java Virtual Machine. Campos estáticos e transitórios não são serializáveis, portanto, se você tiver um campo que não deseja serializar, torne-o temporário ou estático. No caso de um campo estático, ele não é serializado porque um campo estático pertence a uma classe e não a um objeto. Por causa disso, o estado de transição impede que o campo seja serializado. A serialização é usada no Hibernate, JPA e RMI. A serialização também pode ser personalizada. Isso é chamado de serialização personalizada.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION