Builder模式 和 Fluent Interface
Posted ~无关风月~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Builder模式 和 Fluent Interface相关的知识,希望对你有一定的参考价值。
Builder模式
建造者模式(Builder Pattern)也叫做生成器模式。
Separate the construction of a complex object from its representation so that the same construction precess can create different representaions.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)
详见:
https://lovezxm.blog.csdn.net/article/details/118276586
Fluent Interface
连贯接口(fluent interfaces)不仅仅能提供 类型 method chaining 和 Builder模式的方法级联调用,更重要的是能限定方法调用的顺序。
连贯接口不仅仅在提供API,其连贯性带来的可读性和可理解性,也是一种领域语言,是一种Internal DSL。
DSL的核心价值——更加清晰地表达系统中,某一部分的设计意图和业务语义。
本文将介绍,如何通过连贯接口来使用和实现Builder模式。
当我们在构造一个超级复杂的Object的时候。比如某企业级Order订单类这个非常核心而且非常重要,不允许出错的实体类。可能会在编写的过程中漏掉某个setter,从而缺失了某个属性值。
所以我们需要使用这种Fluent Builder模式来避免这类问题:
以邮件实体类为例,我们需要定义一下重要(必需)和可选属性,强制必须填写的是from、to、subject和content,抄送bcc和cc是可选的。
我们需要根据流畅接口的下一个行为(fluent action)去选择返回类型。这种风格的一个很好的优点是方法补完后(intellisense)有助于告诉你接下来要键入什么 —— 有点像 IDE 中的智能提示。
public final class Email {
// To Address. Multiple Address separated by ","
String to;
// From Address
String from;
// Subject of the email
String subject;
// Content of the email
String content;
// BCC optional
String bcc;
// CC Optional
String cc;
/**
* Private constructor to prevent the object initialization
*/
private Email(String to, String from, String subject, String content, String bcc, String cc) {
this.to = to;
this.from = from;
this.subject = subject;
this.content = content;
this.bcc = bcc;
this.cc = cc;
}
public String getTo() {
return to;
}
public String getFrom() {
return from;
}
public String getSubject() {
return subject;
}
public String getContent() {
return content;
}
public String getBcc() {
return bcc;
}
public String getCc() {
return cc;
}
@Override
public String toString() {
return "Email{" +
"to='" + to + '\\'' +
", from='" + from + '\\'' +
", subject='" + subject + '\\'' +
", content='" + content + '\\'' +
", bcc='" + bcc + '\\'' +
", cc='" + cc + '\\'' +
'}';
}
// 为设置属性创建一条接口链,每个方法返回类型是接口链的下一个接口
// Interface to Set From
interface EmailFrom {
EmailTo setFrom(String from);
}
// Interface to Set To
interface EmailTo {
EmailSubject setTo(String to);
}
// Interface to Set subject
interface EmailSubject {
EmailContent setSubject(String subject);
}
// Interface to set Content
interface EmailContent {
EmailCreator setContent(String content);
}
// 对于所有可选属性,只需要在链的最后一个接口创建方法和build方法
// Final Email Creator Class
interface EmailCreator {
EmailCreator setBCC(String bcc);
EmailCreator setCC(String cc);
Email build();
}
/**
* Static class for building the email object
*/
public static class EmailBuilder implements EmailFrom, EmailTo, EmailSubject, EmailContent, EmailCreator {
String to;
String from;
String subject;
String content;
String bcc;
String cc;
/**
* Private emailbuilder to prevent direct object creation
*/
private EmailBuilder() {
}
/**
* Getting the instance method
* @return
*/
public static EmailFrom getInstance() {
return new EmailBuilder();
}
@Override
public EmailTo setFrom(String from) {
this.from = from;
return this;
}
@Override
public EmailSubject setTo(String to) {
this.to = to;
return this;
}
@Override
public EmailContent setSubject(String subject) {
this.subject = subject;
return this;
}
@Override
public EmailCreator setContent(String content) {
this.content = content;
return this;
}
@Override
public EmailBuilder setBCC(String bcc) {
this.bcc = bcc;
return this;
}
@Override
public EmailBuilder setCC(String cc) {
this.cc = cc;
return this;
}
@Override
public Email build() {
return new Email(to, from, subject, content, bcc, cc);
}
}
}
/**
* Test Class
*/
public class EmailTest {
public static void main(String args[]){
//Creating basic email object without cc and bcc
Email email = Email.EmailBuilder.getInstance().setFrom("Test@gmail.com").setTo("mail@gmail.com")
.setSubject("Test with only required Fields").setContent(" Required Field Test").build();
System.out.println(email);
//Creating the full Email Object with cc and bcc
email = Email.EmailBuilder.getInstance().setFrom("Test@gmail.com").setTo("mail@gmail.com")
.setSubject("Test with ALL Fields").setContent(" ALL Field Test").setBCC("bcc@gmail.com")
.setCC("cc@gmail.com").build();
System.out.println(email);
}
}
参考:
【1】Introduction to the Fluent Builder Pattern
【2】Builder Pattern and Fluent Interface
【3】FluentInterface
以上是关于Builder模式 和 Fluent Interface的主要内容,如果未能解决你的问题,请参考以下文章
UIView 的子类。如何通过 Interface Builder 添加?