builder模式听起来挺陌生,但实际在用的时候挺普遍的。当一个类参数比较少的时候,可以直接用构造函数传入,并且进行校验,但是当参数非常多非常复杂的时候应该怎么办,这个时候就需要用到builder模式了。
例子
class Student {
private String name;
private int age;
private String class;
public Student(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.class = builder.class;
}
}
class Builder {
private String name;
private int age;
private String class;
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setClass(String class) {
this.class = class;
return this;
}
public Student build() {
// check parameters
return new Student(this);
}
}
这是builder模式的一个简易例子,从例子可以看到一些简要技巧,builder的每个参数都返回builder自身,这样容易以连贯式表达式书写,在最后build出新的对象。
而builder的用法在很多组件中都有用到,例如说netty
public void server(int port) throws Exception {
final ByteBuf buf = Unpooled.unreleasableBuffer(
Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8")));
EventLoopGroup group = new OioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap(); //1
b.group(group) //2
.channel(OioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {//3
@Override
public void initChannel(SocketChannel ch)
throws Exception {
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { //4
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(buf.duplicate()).addListener(ChannelFutureListener.CLOSE);//5
}
});
}
});
ChannelFuture f = b.bind().sync(); //6
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync(); //7
}
}
这一串连贯式表达式就是builder模式的典型应用。在jdbi3中也有相关的使用,一般来说,一些生命力比较强不断演化的中间件,都会不断用新的优秀的写法改善自身。
小结
builder模式是一种比较常用的设计模式,在常用的中间件初始化时,我们可以留心观察是否用到了builder模式。
网友评论