创建设计模式 - Builder设计模式
今天我们将研究java中的Builder模式。Builder 设计模式是一种创造性的设计模式,如工厂模式和抽象工厂模式。
目录[ 隐藏 ]
生成器设计模式
当Object包含许多属性时,引入了Builder模式来解决Factory和Abstract Factory设计模式的一些问题。
当Object包含许多属性时,Factory和Abstract Factory设计模式存在三个主要问题。
- 从客户端程序传递到Factory类的参数太多,可能容易出错,因为大多数情况下,参数的类型是相同的,而从客户端来说,很难维护参数的顺序。
- 一些参数可能是可选的,但在Factory模式中,我们被迫发送所有需要发送为NULL的参数和可选参数。
- 如果对象很重并且它的创建很复杂,那么所有这些复杂性将成为Factory类的一部分,这会令人困惑。
我们可以通过提供具有所需参数的构造函数然后使用不同的setter方法来设置可选参数来解决大量参数的问题。这种方法的问题是,除非明确设置所有属性,否则Object状态将不一致。
Builder模式通过提供逐步构建对象的方法并提供实际返回最终Object的方法,解决了大量可选参数和不一致状态的问题。
Java中的生成器设计模式
让我们看看如何在java中实现构建器设计模式。
- 首先,您需要创建一个静态嵌套类,然后将所有参数从外部类复制到Builder类。我们应该遵循命名约定,如果类名是,
Computer
那么构建器类应该命名为ComputerBuilder
。 - Java Builder类应该有一个公共构造函数,其中包含所有必需的属性作为参数。
- Java Builder类应具有设置可选参数的方法,并且应在设置可选属性后返回相同的Builder对象。
- 最后一步是
build()
在构建器类中提供一个方法,该方法将返回客户端程序所需的Object。为此,我们需要在Class中使用Builder类作为参数的私有构造函数。
下面是示例构建器模式示例代码,其中我们有一个Computer类和ComputerBuilder类来构建它。
package com.journaldev.design.builder;
public class Computer {
//required parameters
private String HDD;
private String RAM;
//optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public String getHDD() {
return HDD;
}
public String getRAM() {
return RAM;
}
public boolean isGraphicsCardEnabled() {
return isGraphicsCardEnabled;
}
public boolean isBluetoothEnabled() {
return isBluetoothEnabled;
}
private Computer(ComputerBuilder builder) {
this.HDD=builder.HDD;
this.RAM=builder.RAM;
this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
this.isBluetoothEnabled=builder.isBluetoothEnabled;
}
//Builder Class
public static class ComputerBuilder{
// required parameters
private String HDD;
private String RAM;
// optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public ComputerBuilder(String hdd, String ram){
this.HDD=hdd;
this.RAM=ram;
}
public ComputerBuilder setGraphicsCardEnabled(boolean isGraphicsCardEnabled) {
this.isGraphicsCardEnabled = isGraphicsCardEnabled;
return this;
}
public ComputerBuilder setBluetoothEnabled(boolean isBluetoothEnabled) {
this.isBluetoothEnabled = isBluetoothEnabled;
return this;
}
public Computer build(){
return new Computer(this);
}
}
}
请注意,Computer类只有getter方法,没有公共构造函数。因此,获取Computer对象的唯一方法是通过ComputerBuilder类。
这是一个构建器模式示例测试程序,显示如何使用Builder类来获取对象。
package com.journaldev.design.test;
import com.journaldev.design.builder.Computer;
public class TestBuilderPattern {
public static void main(String[] args) {
//Using builder to get the object in a single line of code and
//without any inconsistent state or arguments management issues
Computer comp = new Computer.ComputerBuilder(
"500 GB", "2 GB").setBluetoothEnabled(true)
.setGraphicsCardEnabled(true).build();
}
}
Builder Design Pattern视频教程
最近我上传了一个用于Builder Design Pattern的YouTube视频。我还解释了为什么我认为使用Director类在WikiPedia上定义的构建器模式不是一个非常好的面向对象的方法,以及我们如何使用不同的方法和一个类来实现相同的抽象级别。
请注意,这是我的观点,我觉得设计模式是指导我们,但最终我们必须决定在我们的项目中实现它是否真的有益。我坚信KISS原则。
如果你喜欢这个视频,请分享它,喜欢它并订阅我的频道。如果您认为我错了,或者您有任何意见或反馈,以便我以后可以改进我的视频,请通过此处或YouTube视频页面上的评论告诉我。
JDK中的Builder设计模式示例
Java类中的一些构建器模式示例是;
- java.lang.StringBuilder#append()(未同步)
- java.lang.StringBuffer#append()(synchronized)
这就是java中的构建器设计模式的全部内容。
这种实现的Builder设计模式:当类的属性非常多的时候,通过在类中设置一个内部静态类,内部静态类有很多setter方法,每个setter方法都在设置完属性后,返回内部静态类的示例,最后通过build方法,传入设置属性完毕的内部静态类,来实例化这个属性非常多的类。
当然这个只是Builder模式的一种实现,还有另外一种实现,如下图:
在客户端代码中,无须关心产品对象的具体组装过程,只需确定具体建造者的类型即可,建造者模式将复杂对象的构建与对象的表现分离开来,这样使得同样的构建过程可以创建出不同的表现。
……
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
Product product = director.construct();
……
本文所描述的Builder模式,其实和Director/Builder/ConcreteBuilder -> Product本质一样,而且更加简单,通过链式的传递内部静态类对象,实现了灵活的设置参数,分解了实例化复杂多属性类对象的笨拙性,而且通过只通过一个类和对应内部静态类实现复杂类对象的创建,更加高效和灵活,因为Builder模式的本质就是弥补工厂模式在面对创建复杂对象时的不足,以降低复杂性,并灵活地设置属性。
当然,如果正常情况下,只需要默认配置,那么也可以通过Director来对这个链式调用的过程进行封装,对外只需Product product = director.construct() 就得到需要的复杂对象。
转载来源:https://www.journaldev.com/1425/builder-design-pattern-in-java
Builder设计模式的链式调用:https://blog.csdn.net/qn20126816/article/details/79294696