JavaRush /Java 博客 /Random-ZH /喝咖啡休息#124。生成器设计模式。Java 中的序列化和反序列化如何工作

喝咖啡休息#124。生成器设计模式。Java 中的序列化和反序列化如何工作

已在 Random-ZH 群组中发布

Java 中的构建器设计模式

来源:Medium 在本文中,我们将学习如何使用Builder设计模式来设计和创建类的对象。 喝咖啡休息#124。 生成器设计模式。 Java 中的序列化和反序列化如何工作 - 1

为什么我们需要Builder设计模式?

Builder模式旨在使用与外部类具有相同数据字段的嵌套公共静态类来创建对象。创建Builder模式是为了解决当类对象包含许多字段值和/或数据时工厂抽象工厂设计模式中出现的问题。在我们继续讨论Builder模式之前,让我们先看看对于对象具有多个字段值的场景,FactoryAbstract Factory模式会出现哪些问题:
  1. 从客户端程序传递到Factory类的参数过多可能会导致错误,因为大多数时候参数类型是相同的,并且很难在客户端维护参数的顺序。

  2. 有些参数可能是可选的,但在工厂模式中我们被迫发送所有参数,并且可选参数必须作为NULL文件发送。

  3. 如果对象很“重”并且设计复杂,那么所有这些困难都将成为工厂类的一部分,这往往会导致混乱。

当对象有大量参数时,可以解决上述问题。为此,您只需为构造函数提供所需的参数,然后提供各种setter方法来设置可选参数。请注意,此方法的问题在于,除非明确设置所有属性,否则 对象的状态将保持不一致。

什么是构建器设计模式?

Builder模式通过提供一种逐步构建对象的方法,解决了可选参数较多和状态不一致的问题。这使用了一个实际返回最终对象的方法。

如何在Java中实现Builder设计模式?

如果我们按照以下步骤操作,我们将获得创建对象和检索对象的逐步过程:
  1. 创建一个静态嵌套类作为Builder类,然后将外部类中的所有字段复制到Builder类中。我们必须遵循命名约定,因此如果类名称是Person,那么Builder类应该称为PersonBuilder

  2. Builder类必须有一个公共构造函数,并将所有必需字段作为参数。

  3. Builder类必须具有设置可选参数的方法,并且在设置可选字段后必须返回相同的Builder对象。

  4. 最后一步是在Builder类中提供build()方法,该方法将返回客户端程序所需的对象。为此,我们需要在主类中有一个私有构造函数,并将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.StringBuilderjava.lang.StringBuffer使用Builder模式来构建对象。

Java 中的序列化和反序列化如何工作

来源:Medium 我在实习结束后于今年 1 月份转向了 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 类实现了Serialized,以便其对象可以序列化/反序列化。Person类有两个字段:标识符和名称,在创建该类的实例时,它们的默认值会发生变化。程序中使用的 Serialized接口和其他类都被导入到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();
}
}
}
如您所知,main 方法启动序列化并打印成功消息,否则打印错误消息。为了序列化对象,我们使用ObjectOutputStreamwriteObject方法。

反序列化

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();
}
}
}
反序列化是序列化的逆过程。要从字节序列重建对象,请使用ObjectInputStreamreadObject方法。请注意,为了提供对Person类中字段的访问,该对象将转换为Person数据类型。未实现序列化接口的类对象无法序列化。因此,任何引用实现序列化接口的类的类本身都必须实现序列化接口,否则将引发异常。序列化与平台无关,这意味着正在序列化的字节流可以由另一个 Java 虚拟机反序列化。静态和瞬态字段不可序列化,因此如果您有不想序列化的字段,请将其设为临时或静态。对于静态字段,它不会被序列化,因为静态字段属于类而不是对象。因此,过渡状态会阻止字段被序列化。序列化用于 Hibernate、JPA 和 RMI。序列化也可以定制。这称为自定义序列化。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION