欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java雜談之如何消除代碼中一大串參數(shù)列表

 更新時(shí)間:2021年10月06日 13:26:02   作者:JavaEdge.  
參數(shù)列表和字面意思差不多,主要是表示該參數(shù)數(shù)量不是固定的,可能會(huì)有一個(gè)參數(shù),可能多個(gè),不管多少個(gè)參數(shù),都放到一個(gè)數(shù)組處理,這種參數(shù)叫可變參數(shù)??勺冮L(zhǎng)參數(shù)要放在最后一個(gè)參數(shù)位置處理,但是一個(gè)函數(shù)里面不能有倆種類型的可變參數(shù)

有經(jīng)驗(yàn)的程序員應(yīng)該都見(jiàn)過(guò),一個(gè)方法坐擁幾十上百個(gè)參數(shù)。

方法為何要有參數(shù)?

因?yàn)椴煌椒ㄩg需共享信息。

但方法間共享信息的方式不止一種,除了參數(shù)列表,還有全局變量。但全局變量總能帶來(lái)意外驚喜,所以,取消全局變量也是各大語(yǔ)言的趨勢(shì)。

但方法之間還是要傳遞信息的,不能用全局變量,于是參數(shù)就成了唯一選擇,于是,只要你想到有什么信息要傳給一個(gè)方法,就會(huì)直接它加到參數(shù)列表中,參數(shù)列表也越來(lái)越長(zhǎng)。

長(zhǎng)參數(shù)列表的問(wèn)題

參數(shù)列表過(guò)長(zhǎng),你一個(gè) crud 程序員就很難完全掌控這些邏輯了呀!

所以癥結(jié)是數(shù)量多,解決關(guān)鍵也就在于降低參數(shù)的數(shù)量。

解決方案

聚沙成塔

一個(gè)簡(jiǎn)單的創(chuàng)建博客的方法:

public void createActicle(final String title, 
                       final String introduction,
                       final URL coverUrl,
                       final ActicleType type,
                       final ActicleColumn column,
                       final String protagonists,
                       final String tags,
                       final boolean completed) {
  ...
  Acticle acticle = Acticle.builder
    .title(title) 
    .introduction(introduction)
    .coverUrl(coverUrl)
    .type(type)
    .column(column)
    .protagonists(protagonists)
    .tags(tags)
    .completed(completed)
    .build();
    
  this.repository.save(acticle);
}

參數(shù)列表包含了一篇博客所要擁有的各種信息,比如:博客標(biāo)題、博客簡(jiǎn)介、封面 URL、博客類型、博客歸屬的專欄、主角姓名、博客標(biāo)簽、博客是否完結(jié)…

如果只是想理解邏輯,或許你還會(huì)覺(jué)得參數(shù)列表挺合理,畢竟它把創(chuàng)建一篇博客所需的各種信息都傳給了方法,這也是大部分人面對(duì)一段代碼時(shí)理解問(wèn)題的最初角度。
雖然這樣寫(xiě)代碼容易讓人理解,但這不足以讓你發(fā)現(xiàn)問(wèn)題。

現(xiàn)在產(chǎn)品要求在博客里增加一項(xiàng)信息,標(biāo)識(shí)這部博客是否是簽約博客,也就是這部博客是否可收費(fèi),咋辦?

很簡(jiǎn)單啊!我直接新增一個(gè)參數(shù)。很多屎山就這么來(lái)的,積少成多,量變引起質(zhì)變!

這里所有參數(shù)都是創(chuàng)建博客所必需的。所以,可以做的就是將這些參數(shù)封裝成一個(gè)類,一個(gè)創(chuàng)建博客的參數(shù)類:

public class NewActicleParamters {
  private String title;
  private String introduction;
  private URL coverUrl;
  private ActicleType type;
  private ActicleColumn column;
  private String protagonists;
  private String tags;
  private boolean completed;
  ...
}

這樣參數(shù)列表就只剩下一個(gè)參數(shù)了:

public void createActicle(final NewActicleParamters parameters) {
  ...
}

所以, 將參數(shù)列表封裝成對(duì)象吧 !

只是把一個(gè)參數(shù)列表封裝成一個(gè)類,然后,用到這些參數(shù)的時(shí)候,還需要把它們一個(gè)個(gè)取出來(lái),這會(huì)不會(huì)是多此一舉呢?就像這樣:

public void createActicle(final NewActicleParamters parameters) {
  ...
  Acticle acticle = Acticle.builder
    .title(parameters.getTitle()) 
    .introduction(parameters.getIntroduction())
    .coverUrl(parameters.getCoverUrl())
    .type(parameters.getType())
    .channel(parameters.getChannel())
    .protagonists(parameters.getProtagonists())
    .tags(parameters.getTags())
    .completed(parameters.isCompleted())
    .build();
    
  this.repository.save(acticle);
}

若你也這樣想,說(shuō)明:你還沒(méi)有形成對(duì)軟件設(shè)計(jì)的理解。我們并非簡(jiǎn)單地把參數(shù)封裝成類,站在設(shè)計(jì)角度,這里引入的是一個(gè)新模型。
一個(gè)模型的封裝應(yīng)該以【行為】為基礎(chǔ)。
之前沒(méi)有這個(gè)模型,所以想不到它應(yīng)該有什么行為,現(xiàn)在模型產(chǎn)生了,它就該有自己配套的行為。

那這個(gè)模型的行為是什么?構(gòu)建一個(gè)博客對(duì)象,這很清晰,則代碼就能進(jìn)一步重構(gòu):

public class NewActicleParamters {
  private String title;
  private String introduction;
  private URL coverUrl;
  private ActicleType type;
  private ActicleColumn column;
  private String protagonists;
  private String tags;
  private boolean completed;
  
  public Acticle newActicle() {
    return Acticle.builder
      .title(title) 
      .introduction(introduction)
      .coverUrl(coverUrl)
      .type(type)
      .column(column)
      .protagonists(protagonists)
      .tags(tags)
      .completed(completed)
      .build();
  }
}

創(chuàng)建博客的方法就得到了極大簡(jiǎn)化:

public void createActicle(final NewActicleParamters parameters) {
  ...
  Acticle acticle = parameters.newActicle();
    
  this.repository.save(acticle);
}

“如何擴(kuò)展需求”?如果需求擴(kuò)展,需要增加創(chuàng)建博客所需的內(nèi)容,那這個(gè)參數(shù)列表就是不變的,相對(duì)來(lái)說(shuō),它就是穩(wěn)定的。

那這個(gè)類就會(huì)不斷膨脹,變成一個(gè)大類,那該怎么辦呢?如何解決大類?

動(dòng)靜分離

不是所有情況下,參數(shù)都屬于一個(gè)類:

public void getChapters(final long acticleId, 
                        final HttpClient httpClient,
                        final ChapterProcessor processor) {
  HttpUriRequest request = createChapterRequest(acticleId);
  HttpResponse response = httpClient.execute(request);
  List<Chapter> chapters = toChapters(response);
  processor.process(chapters);
}

根據(jù)博客 ID 獲取其對(duì)應(yīng)章節(jié)信息。
純以參數(shù)個(gè)數(shù)論,參數(shù)數(shù)量不多。

如果你只是看這個(gè)方法,可能很難發(fā)現(xiàn)直接問(wèn)題。絕對(duì)數(shù)量不是關(guān)鍵點(diǎn),參數(shù)列表也應(yīng)該是越少越好。

在這幾個(gè)參數(shù)里面,每次傳進(jìn)來(lái)的 acticleId 都不一樣,隨請(qǐng)求不同而改變。但 httpClient 和 processor 兩個(gè)參數(shù)一樣,因?yàn)槎加邢嗤壿嫞瑳](méi)什么變化。
即acticleId 的變化頻率同 httpClient 和 processor 這兩個(gè)參數(shù)變化頻率不同。

不同的數(shù)據(jù)變動(dòng)方向也是不同關(guān)注點(diǎn)。這里表現(xiàn)出來(lái)的就是典型的動(dòng)數(shù)據(jù)(acticleId)和靜數(shù)據(jù)(httpClient 和 processor),它們是不同關(guān)注點(diǎn),應(yīng)該分離。

具體到這個(gè)場(chǎng)景下,靜態(tài)不變的數(shù)據(jù)完全可以成為這個(gè)方法所在類的一個(gè)字段,而只將每次變動(dòng)的東西作為參數(shù)傳遞就可以了。按照這個(gè)思路,代碼可以改成這個(gè)樣子:

public void getChapters(final long acticleId) {
  HttpUriRequest request = createChapterRequest(acticleId);
  HttpResponse response = this.httpClient.execute(request);
  List<Chapter> chapters = toChapters(response);
  this.processor.process(chapters);
}

這個(gè)壞味道其實(shí)是一個(gè)軟件設(shè)計(jì)問(wèn)題,代碼缺乏應(yīng)有的結(jié)構(gòu),所以,原本應(yīng)該屬于靜態(tài)結(jié)構(gòu)的部分卻以動(dòng)態(tài)參數(shù)的方式傳來(lái)傳去,無(wú)形之中拉長(zhǎng)了參數(shù)列表。

長(zhǎng)參數(shù)列表固然可以用一個(gè)類進(jìn)行封裝,但能夠封裝出這個(gè)類的前提條件是:這些參數(shù)屬于一個(gè)類,有相同變化原因。

如果方法的參數(shù)有不同的變化頻率,就要視情況而定了。對(duì)于靜態(tài)的部分,我們前面已經(jīng)看到了,它可以成為軟件結(jié)構(gòu)的一篇分,而如果有多個(gè)變化頻率,我們還可以封裝出多個(gè)參數(shù)類。

告別標(biāo)記

public void editChapter(final long chapterId, 
                        final String title, 
                        final String content, 
                        final boolean apporved) {
  ...
}

待修改章節(jié)的ID、標(biāo)題和內(nèi)容,最后一個(gè)參數(shù)表示這次修改是否直接審核通過(guò)。

前面幾個(gè)參數(shù)是修改一個(gè)章節(jié)的必要信息,重點(diǎn)在最后這個(gè)參數(shù)。
從業(yè)務(wù)上說(shuō),如果是作者進(jìn)行編輯,之后要經(jīng)過(guò)審核,而如果編輯來(lái)編輯的,那審核就直接通過(guò),因?yàn)榫庉嫳旧戆缪萘藢徍巳说慕巧K?,你發(fā)現(xiàn)了,這個(gè)參數(shù)實(shí)際上是一個(gè)標(biāo)記,標(biāo)志著接下來(lái)的處理流程會(huì)有不同。

使用標(biāo)記參數(shù),是程序員初學(xué)編程時(shí)常用的一種手法。正是這種手法實(shí)在太好用,導(dǎo)致代碼里flag肆意飄蕩。不僅變量里有標(biāo)記,參數(shù)里也有。很多長(zhǎng)參數(shù)列表其中就包含了各種標(biāo)記參數(shù)。

在實(shí)際的代碼中,必須小心翼翼地判斷各個(gè)標(biāo)記當(dāng)前的值,才能做好處理。

解決標(biāo)記參數(shù),一種簡(jiǎn)單的方式就是,將標(biāo)記參數(shù)代表的不同路徑拆分出來(lái)。

這里的一個(gè)方法可以拆分成兩個(gè)方法,一個(gè)方法負(fù)責(zé)“普通的編輯”,另一個(gè)負(fù)責(zé)“可以直接審核通過(guò)的編輯”。

// 普通的編輯,需要審核
public void editChapter(final long chapterId, 
                        final String title, 
                        final String content) {
  ...
}
// 直接審核通過(guò)的編輯
public void editChapterWithApproval(final long chapterId,
                                    final String title,
                                    final String content) {
 ...
}

標(biāo)記參數(shù)在代碼中存在的形式很多,有的是布爾值、枚舉值、字符串或整數(shù)。都可以通過(guò)拆分方法的方式將它們拆開(kāi)。在重構(gòu)中,這種手法叫做移除標(biāo)記參數(shù)(Remove Flag Argument)。

只有短小的代碼,我們才能有更好地把握,而要寫(xiě)出短小的代碼,需要我們能夠“分離關(guān)注點(diǎn)”。

總結(jié)

應(yīng)對(duì)長(zhǎng)參數(shù)列表主要的方式就是減少參數(shù)的數(shù)量,最直接的就是將參數(shù)列表封裝成一個(gè)類。但并不是說(shuō)所有的情況都能封裝成類來(lái)解決,我們還要分析是否所有的參數(shù)都有相同的變動(dòng)頻率。

變化頻率相同,則封裝成一個(gè)類。
變化頻率不同的話:

  • 靜態(tài)不變的,可以成為軟件結(jié)構(gòu)的一篇分
  • 多個(gè)變化頻率的,可以封裝成幾個(gè)類

此外,參數(shù)列表中經(jīng)常會(huì)出現(xiàn)標(biāo)記參數(shù),這是參數(shù)列表變長(zhǎng)的另一個(gè)重要原因。對(duì)于這種標(biāo)記參數(shù),一種解決方案就是根據(jù)這些標(biāo)記參數(shù),將方法拆分成多個(gè)方法。

減少參數(shù)列表,越少越好。

到此這篇關(guān)于Java雜談之如何消除代碼中一大串參數(shù)列表的文章就介紹到這了,更多相關(guān)Java 參數(shù)列表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot整合mybatis-plus基于注解實(shí)現(xiàn)一對(duì)一(一對(duì)多)查詢功能

    springboot整合mybatis-plus基于注解實(shí)現(xiàn)一對(duì)一(一對(duì)多)查詢功能

    這篇文章主要介紹了springboot整合mybatis-plus基于純注解實(shí)現(xiàn)一對(duì)一(一對(duì)多)查詢功能,因?yàn)楸救瞬捎玫氖莝pring-boot進(jìn)行開(kāi)發(fā),本身springboot就提倡采用不用配置自動(dòng)配置的方式,所以真心希望mybatis(不是mybatis-plus)這點(diǎn)需要繼續(xù)努力
    2021-09-09
  • java中LinkedList使用迭代器優(yōu)化移除批量元素原理

    java中LinkedList使用迭代器優(yōu)化移除批量元素原理

    本文主要介紹了java中LinkedList使用迭代器優(yōu)化移除批量元素原理,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • java中動(dòng)態(tài)代理的實(shí)現(xiàn)

    java中動(dòng)態(tài)代理的實(shí)現(xiàn)

    本篇文章主要介紹了Java中兩種動(dòng)態(tài)代理的實(shí)現(xiàn):jdk動(dòng)態(tài)代理;cglib動(dòng)態(tài)代理。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • Java簡(jiǎn)單數(shù)組排序(冒泡法)

    Java簡(jiǎn)單數(shù)組排序(冒泡法)

    這篇文章主要介紹了Java簡(jiǎn)單數(shù)組排序,實(shí)例分析了基于冒泡法實(shí)現(xiàn)數(shù)組排序的相關(guān)技巧,簡(jiǎn)單實(shí)用,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-10-10
  • Java BigDecimal使用及基本運(yùn)算(推薦)

    Java BigDecimal使用及基本運(yùn)算(推薦)

    Java在java.math包中提供的API類BigDecimal,用來(lái)對(duì)超過(guò)16位有效位的數(shù)進(jìn)行精確的運(yùn)算。這篇文章主要介紹了Java BigDecimal使用指南針(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • GSON實(shí)現(xiàn)Java對(duì)象與JSON格式對(duì)象相互轉(zhuǎn)換的完全教程

    GSON實(shí)現(xiàn)Java對(duì)象與JSON格式對(duì)象相互轉(zhuǎn)換的完全教程

    GSON是Google編寫(xiě)并在在GitHub上開(kāi)源的Java序列化與反序列化JSON的類庫(kù),今天我們就來(lái)總結(jié)一下使用GSON實(shí)現(xiàn)Java對(duì)象與JSON格式對(duì)象相互轉(zhuǎn)換的完全教程
    2016-06-06
  • SpringMVC如何把后臺(tái)文件打印到前臺(tái)

    SpringMVC如何把后臺(tái)文件打印到前臺(tái)

    這篇文章主要介紹了SpringMVC如何把后臺(tái)文件打印到前臺(tái),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java日期與時(shí)間類原理解析

    Java日期與時(shí)間類原理解析

    這篇文章主要介紹了Java日期與時(shí)間類原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • java實(shí)現(xiàn)簡(jiǎn)單的圖書(shū)管理系統(tǒng)

    java實(shí)現(xiàn)簡(jiǎn)單的圖書(shū)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單的圖書(shū)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Eclipse不自動(dòng)編譯java文件的終極解決方法

    Eclipse不自動(dòng)編譯java文件的終極解決方法

    這篇文章主要介紹了Eclipse不自動(dòng)編譯java文件的終極解決方法,需要的朋友可以參考下
    2015-12-12

最新評(píng)論