日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 管道设计_使用管道流实现Java 8阶段构建器

發(fā)布時(shí)間:2025/3/20 java 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 管道设计_使用管道流实现Java 8阶段构建器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Step builder多階段步驟構(gòu)造器模式是一種對(duì)象創(chuàng)建軟件設(shè)計(jì)模式。與傳統(tǒng)構(gòu)建器模式進(jìn)行比較時(shí),步驟構(gòu)建器模式提供了一些簡(jiǎn)潔的好處。Step Builder模式的主要優(yōu)勢(shì)之一是為客戶提供有關(guān)如何使用API??的指南。它可以看作是構(gòu)建器模式和狀態(tài)機(jī)的混合,事實(shí)上,這種模式通常被稱為構(gòu)建對(duì)象的向?qū)А?/p>

優(yōu)點(diǎn)

通過對(duì)象創(chuàng)建過程逐步為API提供用戶指南。

一旦對(duì)象處于一致狀態(tài),API用戶就可以調(diào)用構(gòu)建器的build()方法。

減少了創(chuàng)建不一致對(duì)象實(shí)例的機(jī)會(huì)。

對(duì)必填字段進(jìn)行排序初始化。

流暢的API。

無需為字段驗(yàn)證提供validate()方法。

缺點(diǎn)

實(shí)現(xiàn)模式本身所需的代碼可讀性低。

沒有eclipse插件來幫助代碼生成。(另一方面,Builder模式生成器有很多代碼生成器)。

案例:

由于Step Builder模式是一種創(chuàng)建性設(shè)計(jì)模式,因此我們將重點(diǎn)放在其目的 - 創(chuàng)建對(duì)象上。

API使用示例如下所示:

Email email =

Email.builder().from(EmailAddress.of("Microservices Weekly "))

.to(EmailAddress.of("svlada@gmail.com"))

.subject(Subject.of("Subject"))

.content(Content.of("Test email"))

.build();

這個(gè)API內(nèi)部是如何實(shí)現(xiàn)的?

public class Email {

private EmailAddress from;

private List to;

private List cc;

private List bcc;

private Subject subject;

private Content content;

public static FromStep builder() {

return new Builder();

}

public interface FromStep {

ToStep from(EmailAddress from);

}

public interface ToStep {

SubjectStep to(EmailAddress... from);

}

public interface SubjectStep {

ContentStep subject(Subject subject);

}

public interface ContentStep {

Build content(Content content);

}

public interface Build {

Email build();

Build cc(EmailAddress... cc);

Build bcc(EmailAddress... bcc);

}

public static class Builder implements FromStep, ToStep, SubjectStep, ContentStep, Build {

private EmailAddress from;

private List to;

private List cc;

private List bcc;

private Subject subject;

private Content content;

@Override

public Email build() {

return new Email(this);

}

@Override

public Build cc(EmailAddress... cc) {

Objects.requireNonNull(cc);

this.cc = new ArrayList(Arrays.asList(cc));

return this;

}

@Override

public Build bcc(EmailAddress... bcc) {

Objects.requireNonNull(bcc);

this.bcc = new ArrayList(Arrays.asList(bcc));

return this;

}

@Override

public Build content(Content content) {

Objects.requireNonNull(content);

this.content = content;

return this;

}

@Override

public ContentStep subject(Subject subject) {

Objects.requireNonNull(subject);

this.subject = subject;

return this;

}

@Override

public SubjectStep to(EmailAddress... to) {

Objects.requireNonNull(to);

this.to = new ArrayList(Arrays.asList(to));

return this;

}

@Override

public ToStep from(EmailAddress from) {

Objects.requireNonNull(from);

this.from = from;

return this;

}

}

private Email(Builder builder) {

this.from = builder.from;

this.to = builder.to;

this.cc = builder.cc;

this.bcc = builder.bcc;

this.subject = builder.subject;

this.content = builder.content;

}

public EmailAddress getFrom() {

return from;

}

public List getTo() {

return to;

}

public List getCc() {

return cc;

}

public List getBcc() {

return bcc;

}

public Subject getSubject() {

return subject;

}

public Content getContent() {

return content;

}

}

實(shí)施的經(jīng)驗(yàn)法則:

向您的類添加依賴項(xiàng)。建議將private修飾符添加到類屬性中。

將每個(gè)創(chuàng)建步驟定義為基類中的內(nèi)部接口。

每個(gè)創(chuàng)建步驟都應(yīng)該返回鏈中的下一步(界面)。

最后一步應(yīng)該是名為“Build”的接口,它將提供build()方法。

定義一個(gè)內(nèi)部靜態(tài)Builder類,它實(shí)現(xiàn)所有已定義的步驟。

實(shí)現(xiàn)步驟接口方法。

新案例:

public static class Coffee {

private final CoffeeType type; // Compulsory, one of arabica, robusta, moka...private final Quantity quantity;// Compulsoryprivate final Optional sugar;

private final Optional cream;

}

@FunctionalInterface

interface RequireCoffeeType {

RequireQuantity coffeeType(CoffeeType type);

}

@FunctionalInterface

interface RequireQuantity {

FinalStage quantity(Quantity quantity);

}

public final class FinalStage {

private final CoffeeType type;// Obtained through the staged builderprivate final Quantity quantity;// Obtained through the staged builderprivate Optional sugar;// Regular builder for this optional fieldprivate Optional cream;// Regular builder for this optional field// ....public Coffee build() {

return new Coffee(type, quantity, sugar, cream);

}

}

public static RequireCoffeeType builder() {

return type -> quantity -> new FinalStage(type, quantity);

}

它可以強(qiáng)制調(diào)用者調(diào)用所有階段,最終獲得構(gòu)建方法,并確保不會(huì)忘記強(qiáng)制階段,

遵循這種模式很難:

很難重用上面定義的階段(功能接口)

很難在階段提出替代選擇。

讓我們提出我們想要構(gòu)建的以下事件:

class UserConnected implements Event {

private final User user;

private final MailboxSession.SessionId sessionId;

// Constructor & getters}

class MailboxCreated implements Event {

private final User user;

private final MailboxSession.SessionId sessionId;

private final MailboxId mailboxId;// Constructor & getters}

這是兩個(gè)創(chuàng)建事件,分別是用戶連接上的事件和郵箱已經(jīng)創(chuàng)建的事件。由于我們的事件具有類似的結(jié)構(gòu),我們最終會(huì)得到大量重復(fù)的代碼!

使用當(dāng)前模式定義,分階段構(gòu)建器看起來像這樣,沒有其他選擇,并且階段重用:

public static class UserConnectedBuilder {

@FunctionalInterface

public interface RequireUser {

RequireSessionId user(User user);

}

@FunctionalInterface

public interface RequireSessionId {

FinalStage sessionId(MailboxSession.SessionId sessionId);

}

public static class FinalStage {

private final User user;

private final MailboxSession.SessionId sessionId;

// constructorpublic UserConnected build() {

return new UserConnected(user, sessionId);

}

}

public static RequireUser builder() {

return user -> sessionId -> new FinalStage(user, sessionId);

}

}

public static class MailboxCreatedBuilder {

@FunctionalInterface

public interface RequireUser {

RequireSessionId user(User user);

}

@FunctionalInterface

public interface RequireSessionId {

RequireMailboxId sessionId(MailboxSession.SessionId sessionId);

}

@FunctionalInterface

public interface RequireMailboxId {

FinalStage mailboxId(MailboxId mailboxId);

}

public static class FinalStage {

private final User user;

private final MailboxSession.SessionId sessionId;

private final MailboxId mailboxId;// constructorpublic MailboxCreated build() {

return new MailboxCreated(user, sessionId, mailboxId);

}

}

public static RequireUser builder() {

return user -> sessionId -> mailboxId -> new FinalStage(user, sessionId, mailboxId);

}

}

由于我們的事件具有類似的結(jié)構(gòu),我們最終會(huì)得到大量重復(fù)的代碼!

我們可以看到,作為調(diào)用者,我們還需要明確指定每個(gè)階段:

MailboxCreatedBuilder.builder()

.user(User.fromUsername("bob"))

.sessionId(SessionId.of(45))

.mailboxId(MailboxId.of(15))

.build();

MailboxCreatedBuilder.builder()// .mailboxSession(session) // not allowed.user(session.getUser())

.sessionId(session.getId())

.mailboxId(MailboxId.of(15))

.build();

希望我們可以使用一些Java特異功能來克服這些限制......

具有泛型的獨(dú)立階段

通過使我們的階段成為通用的,我們可以讓調(diào)用者指定下一個(gè)階段(通過構(gòu)建器方法簽名),這將使階段重用和解除彼此之間的階段。

使用默認(rèn)方法的替代(跳過階段)

我們可以定義將兩個(gè)階段組合在一起的“元階段”。然后,“元階段”可以公開一種默認(rèn)方法,允許將兩個(gè)階段分解為單個(gè)階段。

上面的例子現(xiàn)在看起來像這樣:

@FunctionalInterface

public interface RequireUser {

T user(User user);

}

@FunctionalInterface

public interface RequireSessionId {

T sessionId(MailboxSession.SessionId sessionId);

}

@FunctionalInterface // "meta-stage" session combining to stages into onepublic interface RequireSession extends RequireUser> {

default T session(MailboxSession session) {

return user(session.getUser())

.sessionId(session.getId());

}

}

@FunctionalInterface

public interface RequireMailboxId {

T mailboxId(MailboxId mailboxId);

}

public static class UserConnectedBuilder {

public static class FinalStage {

private final User user;

private final MailboxSession.SessionId sessionId;// constructorpublic UserConnected build() {

return new UserConnected(user, sessionId);

}

}

public static RequireSession builder() {

return user -> sessionId -> new FinalStage(user, sessionId);

}

}

public static class MailboxCreatedBuilder {

public static class FinalStage {

private final User user;

private final MailboxSession.SessionId sessionId;

private final MailboxId mailboxId;// constructorpublic MailboxCreated build() {

return new MailboxCreated(user, sessionId, mailboxId);

}

}

public static RequireSession> builder() {

return user -> sessionId -> mailboxId -> new FinalStage(user, sessionId, mailboxId);

}

}

現(xiàn)在,用戶可以獲得所需的便捷方法,更不用說代碼共享了......

MailboxCreatedBuilder.builder()

.user(User.fromUsername("bob"))

.sessionId(SessionId.of(45))

.mailboxId(MailboxId.of(15))

.build();

MailboxCreatedBuilder.builder()

.mailboxSession(session)// now allowed.mailboxId(MailboxId.of(15))

.build();

此外,構(gòu)建器方法類型顯式地向調(diào)用者公開所需的階段,而不是僅暴露下一個(gè)階段......

總結(jié)

以上是生活随笔為你收集整理的java 管道设计_使用管道流实现Java 8阶段构建器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。