国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】82 | 開(kāi)源實(shí)戰(zhàn)三(中):剖析Google Guava中用到的幾種設(shè)計(jì)模式

這篇具有很好參考價(jià)值的文章主要介紹了【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】82 | 開(kāi)源實(shí)戰(zhàn)三(中):剖析Google Guava中用到的幾種設(shè)計(jì)模式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

上一節(jié)課,我們通過(guò) Google Guava 這樣一個(gè)優(yōu)秀的開(kāi)源類庫(kù),講解了如何在業(yè)務(wù)開(kāi)發(fā)中,發(fā)現(xiàn)跟業(yè)務(wù)無(wú)關(guān)、可以復(fù)用的通用功能模塊,并將它們從業(yè)務(wù)代碼中抽離出來(lái),設(shè)計(jì)開(kāi)發(fā)成獨(dú)立的類庫(kù)、框架或功能組件。

今天,我們?cè)賮?lái)學(xué)習(xí)一下,Google Guava 中用到的幾種經(jīng)典設(shè)計(jì)模式:Builder 模式、Wrapper 模式,以及之前沒(méi)講過(guò)的 Immutable 模式。

話不多說(shuō),讓我們正式開(kāi)始今天的學(xué)習(xí)吧!

Builder 模式在 Guava 中的應(yīng)用

在項(xiàng)目開(kāi)發(fā)中,我們經(jīng)常用到緩存。它可以非常有效地提高訪問(wèn)速度。
常用的緩存系統(tǒng)有 Redis、Memcache 等。但是,如果要緩存的數(shù)據(jù)比較少,我們完全沒(méi)必要在項(xiàng)目中獨(dú)立部署一套緩存系統(tǒng)。畢竟系統(tǒng)都有一定出錯(cuò)的概率,項(xiàng)目中包含的系統(tǒng)越多,那組合起來(lái),項(xiàng)目整體出錯(cuò)的概率就會(huì)升高,可用性就會(huì)降低。同時(shí),多引入一個(gè)系統(tǒng)就要多維護(hù)一個(gè)系統(tǒng),項(xiàng)目維護(hù)的成本就會(huì)變高。

取而代之,我們可以在系統(tǒng)內(nèi)部構(gòu)建一個(gè)內(nèi)存緩存,跟系統(tǒng)集成在一起開(kāi)發(fā)、部署。那如何構(gòu)建內(nèi)存緩存呢?我們可以基于 JDK 提供的類,比如 HashMap,從零開(kāi)始開(kāi)發(fā)內(nèi)存緩存。不過(guò),從零開(kāi)發(fā)一個(gè)內(nèi)存緩存,涉及的工作就會(huì)比較多,比如緩存淘汰策略等。為了簡(jiǎn)化開(kāi)發(fā),我們就可以使用 Google Guava 提供的現(xiàn)成的緩存工具類 com.google.common.cache.*。
使用 Google Guava 來(lái)構(gòu)建內(nèi)存緩存非常簡(jiǎn)單,我寫(xiě)了一個(gè)例子貼在了下面,你可以看下。

public class CacheDemo {
  public static void main(String[] args) {
    Cache<String, String> cache = CacheBuilder.newBuilder()
            .initialCapacity(100)
            .maximumSize(1000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();
    cache.put("key1", "value1");
    String value = cache.getIfPresent("key1");
    System.out.println(value);
  }
}

從上面的代碼中,我們可以發(fā)現(xiàn),Cache 對(duì)象是通過(guò) CacheBuilder 這樣一個(gè) Builder 類來(lái)創(chuàng)建的。為什么要由 Builder 類來(lái)創(chuàng)建 Cache 對(duì)象呢?我想這個(gè)問(wèn)題應(yīng)該對(duì)你來(lái)說(shuō)沒(méi)難度了吧。

你可以先想一想,然后再來(lái)看我的回答。構(gòu)建一個(gè)緩存,需要配置 n 多參數(shù),比如過(guò)期時(shí)間、淘汰策略、最大緩存大小等等。相應(yīng)地,Cache 類就會(huì)包含 n 多成員變量。我們需要在構(gòu)造函數(shù)中,設(shè)置這些成員變量的值,但又不是所有的值都必須設(shè)置,設(shè)置哪些值由用戶來(lái)決定。為了滿足這個(gè)需求,我們就需要定義多個(gè)包含不同參數(shù)列表的構(gòu)造函數(shù)。

為了避免構(gòu)造函數(shù)的參數(shù)列表過(guò)長(zhǎng)、不同的構(gòu)造函數(shù)過(guò)多,我們一般有兩種解決方案。其中,一個(gè)解決方案是使用 Builder 模式;另一個(gè)方案是先通過(guò)無(wú)參構(gòu)造函數(shù)創(chuàng)建對(duì)象,然后再通過(guò) setXXX() 方法來(lái)逐一設(shè)置需要的設(shè)置的成員變量。

那我再問(wèn)你一個(gè)問(wèn)題,為什么 Guava 選擇第一種而不是第二種解決方案呢?使用第二種解決方案是否也可以呢?答案是不行的。至于為什么,我們看下源碼就清楚了。我把 CacheBuilder 類中的 build() 函數(shù)摘抄到了下面,你可以先看下。

public <K1 extends K, V1 extends V> Cache<K1, V1> build() {
  this.checkWeightWithWeigher();
  this.checkNonLoadingCache();
  return new LocalManualCache(this);
}
private void checkNonLoadingCache() {
  Preconditions.checkState(this.refreshNanos == -1L, "refreshAfterWrite requires a LoadingCache");
}
private void checkWeightWithWeigher() {
  if (this.weigher == null) {
    Preconditions.checkState(this.maximumWeight == -1L, "maximumWeight requires weigher");
  } else if (this.strictParsing) {
    Preconditions.checkState(this.maximumWeight != -1L, "weigher requires maximumWeight");
  } else if (this.maximumWeight == -1L) {
    logger.log(Level.WARNING, "ignoring weigher specified without maximumWeight");
  }
}

看了代碼,你是否有了答案呢?實(shí)際上,答案我們?cè)谥v Builder 模式的時(shí)候已經(jīng)講過(guò)了?,F(xiàn)在,我們?cè)俳Y(jié)合 CacheBuilder 的源碼重新說(shuō)下。
必須使用 Builder 模式的主要原因是,在真正構(gòu)造 Cache 對(duì)象的時(shí)候,我們必須做一些必要的參數(shù)校驗(yàn),也就是 build() 函數(shù)中前兩行代碼要做的工作。如果采用無(wú)參默認(rèn)構(gòu)造函數(shù)加 setXXX() 方法的方案,這兩個(gè)校驗(yàn)就無(wú)處安放了。而不經(jīng)過(guò)校驗(yàn),創(chuàng)建的 Cache 對(duì)象有可能是不合法、不可用的。

Wrapper 模式在 Guava 中的應(yīng)用

在 Google Guava 的 collection 包路徑下,有一組以 Forwarding 開(kāi)頭命名的類。我截了這些類中的一部分貼到了下面,你可以看下。

【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】82 | 開(kāi)源實(shí)戰(zhàn)三(中):剖析Google Guava中用到的幾種設(shè)計(jì)模式
這組 Forwarding 類很多,但實(shí)現(xiàn)方式都很相似。我摘抄了其中的 ForwardingCollection 中的部分代碼到這里,你可以下先看下代碼,然后思考下這組 Forwarding 類是干什么用的。

@GwtCompatible
public abstract class ForwardingCollection<E> extends ForwardingObject implements Collection<E> {
  protected ForwardingCollection() {
  }
  protected abstract Collection<E> delegate();
  public Iterator<E> iterator() {
    return this.delegate().iterator();
  }
  public int size() {
    return this.delegate().size();
  }
  @CanIgnoreReturnValue
  public boolean removeAll(Collection<?> collection) {
    return this.delegate().removeAll(collection);
  }
  public boolean isEmpty() {
    return this.delegate().isEmpty();
  }
  public boolean contains(Object object) {
    return this.delegate().contains(object);
  }
  @CanIgnoreReturnValue
  public boolean add(E element) {
    return this.delegate().add(element);
  }
  @CanIgnoreReturnValue
  public boolean remove(Object object) {
    return this.delegate().remove(object);
  }
  public boolean containsAll(Collection<?> collection) {
    return this.delegate().containsAll(collection);
  }
  @CanIgnoreReturnValue
  public boolean addAll(Collection<? extends E> collection) {
    return this.delegate().addAll(collection);
  }
  @CanIgnoreReturnValue
  public boolean retainAll(Collection<?> collection) {
    return this.delegate().retainAll(collection);
  }
  public void clear() {
    this.delegate().clear();
  }
  public Object[] toArray() {
    return this.delegate().toArray();
  }
  
  //...省略部分代碼...
}

光看 ForwardingCollection 的代碼實(shí)現(xiàn),你可能想不到它的作用。我再給點(diǎn)提示,舉一個(gè)它的用法示例,如下所示:

public class AddLoggingCollection<E> extends ForwardingCollection<E> {
  private static final Logger logger = LoggerFactory.getLogger(AddLoggingCollection.class);
  private Collection<E> originalCollection;
  public AddLoggingCollection(Collection<E> originalCollection) {
    this.originalCollection = originalCollection;
  }
  @Override
  protected Collection delegate() {
    return this.originalCollection;
  }
  @Override
  public boolean add(E element) {
    logger.info("Add element: " + element);
    return this.delegate().add(element);
  }
  @Override
  public boolean addAll(Collection<? extends E> collection) {
    logger.info("Size of elements to add: " + collection.size());
    return this.delegate().addAll(collection);
  }
}

結(jié)合源碼和示例,我想你應(yīng)該知道這組 Forwarding 類的作用了吧?
在上面的代碼中,AddLoggingCollection 是基于代理模式實(shí)現(xiàn)的一個(gè)代理類,它在原始 Collection 類的基礎(chǔ)之上,針對(duì)“add”相關(guān)的操作,添加了記錄日志的功能。
我們前面講到,代理模式、裝飾器、適配器模式可以統(tǒng)稱為 Wrapper 模式,通過(guò) Wrapper 類二次封裝原始類。它們的代碼實(shí)現(xiàn)也很相似,都可以通過(guò)組合的方式,將 Wrapper 類的函數(shù)實(shí)現(xiàn)委托給原始類的函數(shù)來(lái)實(shí)現(xiàn)。

public interface Interf {
  void f1();
  void f2();
}
public class OriginalClass implements Interf {
  @Override
  public void f1() { //... }
  @Override
  public void f2() { //... }
}
public class WrapperClass implements Interf {
  private OriginalClass oc;
  public WrapperClass(OriginalClass oc) {
    this.oc = oc;
  }
  @Override
  public void f1() {
    //...附加功能...
    this.oc.f1();
    //...附加功能...
  }
  @Override
  public void f2() {
    this.oc.f2();
  }
}

實(shí)際上,這個(gè) ForwardingCollection 類是一個(gè)“默認(rèn) Wrapper 類”或者叫“缺省 Wrapper 類”。這類似于在裝飾器模式那一節(jié)課中,講到的 FilterInputStream 缺省裝飾器類。你可以再重新看下第 50 講裝飾器模式的相關(guān)內(nèi)容。
如果我們不使用這個(gè) ForwardinCollection 類,而是讓 AddLoggingCollection 代理類直接實(shí)現(xiàn) Collection 接口,那 Collection 接口中的所有方法,都要在 AddLoggingCollection 類中實(shí)現(xiàn)一遍,而真正需要添加日志功能的只有 add() 和 addAll() 兩個(gè)函數(shù),其他函數(shù)的實(shí)現(xiàn),都只是類似 Wrapper 類中 f2() 函數(shù)的實(shí)現(xiàn)那樣,簡(jiǎn)單地委托給原始 collection 類對(duì)象的對(duì)應(yīng)函數(shù)。

為了簡(jiǎn)化 Wrapper 模式的代碼實(shí)現(xiàn),Guava 提供一系列缺省的 Forwarding 類。用戶在實(shí)現(xiàn)自己的 Wrapper 類的時(shí)候,基于缺省的 Forwarding 類來(lái)擴(kuò)展,就可以只實(shí)現(xiàn)自己關(guān)心的方法,其他不關(guān)心的方法使用缺省 Forwarding 類的實(shí)現(xiàn),就像 AddLoggingCollection 類的實(shí)現(xiàn)那樣。

Immutable 模式在 Guava 中的應(yīng)用

Immutable 模式,中文叫作不變模式,它并不屬于經(jīng)典的 23 種設(shè)計(jì)模式,但作為一種較常用的設(shè)計(jì)思路,可以總結(jié)為一種設(shè)計(jì)模式來(lái)學(xué)習(xí)。之前在理論部分,我們只稍微提到過(guò) Immutable 模式,但沒(méi)有獨(dú)立的拿出來(lái)詳細(xì)講解,我們這里借 Google Guava 再補(bǔ)充講解一下。
一個(gè)對(duì)象的狀態(tài)在對(duì)象創(chuàng)建之后就不再改變,這就是所謂的不變模式。其中涉及的類就是不變類(Immutable Class),對(duì)象就是不變對(duì)象(Immutable Object)。在 Java 中,最常用的不變類就是 String 類,String 對(duì)象一旦創(chuàng)建之后就無(wú)法改變。

不變模式可以分為兩類,一類是普通不變模式,另一類是深度不變模式(Deeply Immutable Pattern)。普通的不變模式指的是,對(duì)象中包含的引用對(duì)象是可以改變的。如果不特別說(shuō)明,通常我們所說(shuō)的不變模式,指的就是普通的不變模式。深度不變模式指的是,對(duì)象包含的引用對(duì)象也不可變。它們兩個(gè)之間的關(guān)系,有點(diǎn)類似之前講過(guò)的淺拷貝和深拷貝之間的關(guān)系。我舉了一個(gè)例子來(lái)進(jìn)一步解釋一下,代碼如下所示:

// 普通不變模式
public class User {
  private String name;
  private int age;
  private Address addr;
  
  public User(String name, int age, Address addr) {
    this.name = name;
    this.age = age;
    this.addr = addr;
  }
  // 只有g(shù)etter方法,無(wú)setter方法...
}
public class Address {
  private String province;
  private String city;
  public Address(String province, String city) {
    this.province = province;
    this.city= city;
  }
  // 有g(shù)etter方法,也有setter方法...
}
// 深度不變模式
public class User {
  private String name;
  private int age;
  private Address addr;
  
  public User(String name, int age, Address addr) {
    this.name = name;
    this.age = age;
    this.addr = addr;
  }
  // 只有g(shù)etter方法,無(wú)setter方法...
}
public class Address {
  private String province;
  private String city;
  public Address(String province, String city) {
    this.province = province;
    this.city= city;
  }
  // 只有g(shù)etter方法,無(wú)setter方法..
}

在某個(gè)業(yè)務(wù)場(chǎng)景下,如果一個(gè)對(duì)象符合創(chuàng)建之后就不會(huì)被修改這個(gè)特性,那我們就可以把它設(shè)計(jì)成不變類。顯式地強(qiáng)制它不可變,這樣能避免意外被修改。那如何將一個(gè)不變類呢?方法很簡(jiǎn)單,只要這個(gè)類滿足:所有的成員變量都通過(guò)構(gòu)造函數(shù)一次性設(shè)置好,不暴露任何 set 等修改成員變量的方法。除此之外,因?yàn)閿?shù)據(jù)不變,所以不存在并發(fā)讀寫(xiě)問(wèn)題,因此不變模式常用在多線程環(huán)境下,來(lái)避免線程加鎖。所以,不變模式也常被歸類為多線程設(shè)計(jì)模式。

接下來(lái),我們來(lái)看一種特殊的不變類,那就是不變集合。Google Guava 針對(duì)集合類(Collection、List、Set、Map…)提供了對(duì)應(yīng)的不變集合類(ImmutableCollection、ImmutableList、ImmutableSet、ImmutableMap…)。剛剛我們講過(guò),不變模式分為兩種,普通不變模式和深度不變模式。Google Guava 提供的不變集合類屬于前者,也就是說(shuō),集合中的對(duì)象不會(huì)增刪,但是對(duì)象的成員變量(或叫屬性值)是可以改變的。
實(shí)際上,Java JDK 也提供了不變集合類(UnmodifiableCollection、UnmodifiableList、UnmodifiableSet、UnmodifiableMap…)。那它跟 Google Guava 提供的不變集合類的區(qū)別在哪里呢?我舉個(gè)例子你就明白了,代碼如下所示:

public class ImmutableDemo {
  public static void main(String[] args) {
    List<String> originalList = new ArrayList<>();
    originalList.add("a");
    originalList.add("b");
    originalList.add("c");
    List<String> jdkUnmodifiableList = Collections.unmodifiableList(originalList);
    List<String> guavaImmutableList = ImmutableList.copyOf(originalList);
    //jdkUnmodifiableList.add("d"); // 拋出UnsupportedOperationException
    // guavaImmutableList.add("d"); // 拋出UnsupportedOperationException
    originalList.add("d");
    print(originalList); // a b c d
    print(jdkUnmodifiableList); // a b c d
    print(guavaImmutableList); // a b c
  }
  private static void print(List<String> list) {
    for (String s : list) {
      System.out.print(s + " ");
    }
    System.out.println();
  }
}

重點(diǎn)回顧

好了,今天的內(nèi)容到此就講完了。我們一塊來(lái)總結(jié)回顧一下,你需要重點(diǎn)掌握的內(nèi)容。
今天我們學(xué)習(xí)了 Google Guava 中都用到的幾個(gè)設(shè)計(jì)模式:Builder 模式、Wrapper 模式、Immutable 模式。還是那句話,內(nèi)容本身不重要,你也不用死記硬背 Google Guava 的某某類用到了某某設(shè)計(jì)模式。實(shí)際上,我想通過(guò)這些源碼的剖析,傳達(dá)給你下面這些東西。

我們?cè)陂喿x源碼的時(shí)候,要問(wèn)問(wèn)自己,為什么它要這么設(shè)計(jì)?不這么設(shè)計(jì)行嗎?還有更好的設(shè)計(jì)嗎?實(shí)際上,很多人缺少這種“質(zhì)疑”精神,特別是面對(duì)權(quán)威(經(jīng)典書(shū)籍、著名源碼、權(quán)威人士)的時(shí)候。

我覺(jué)得我本人是最不缺質(zhì)疑精神的一個(gè)人,我喜歡挑戰(zhàn)權(quán)威,喜歡以理服人。就好比在今天的講解中,我把 ForwardingCollection 等類理解為缺省 Wrapper 類,可以用在裝飾器、代理、適配器三種 Wrapper 模式中,簡(jiǎn)化代碼編寫(xiě)。如果你去看 Google Guava 在 GitHub 上的 Wiki,你會(huì)發(fā)現(xiàn),它對(duì) ForwardingCollection 類的理解跟我是不一樣的。它把 ForwardingCollection 類單純地理解為缺省的裝飾器類,只用在裝飾器模式中。我個(gè)人覺(jué)得我的理解更加好些,不知道你怎么認(rèn)為呢?

除此之外,在專欄的最開(kāi)始,我也講到,學(xué)習(xí)設(shè)計(jì)模式能讓你更好的閱讀源碼、理解源碼。如果我們沒(méi)有之前的理論學(xué)習(xí),那對(duì)于很多源碼的閱讀,可能都只停留在走馬觀花的層面上,根本學(xué)習(xí)不到它的精髓。這就好比今天講到的 CacheBuilder。我想大部分人都知道它是利用了 Builder 模式,但如果對(duì) Builder 模式?jīng)]有深入的了解,很少人能講清楚為什么要用 Builder 模式,不用構(gòu)造函數(shù)加 set 方法的方式來(lái)實(shí)現(xiàn)。

課堂討論

從最后一段代碼中,我們可以發(fā)現(xiàn),JDK 不變集合和 Google Guava 不變集合都不可增刪數(shù)據(jù)。但是,當(dāng)原始集合增加數(shù)據(jù)之后,JDK 不變集合的數(shù)據(jù)隨之增加,而 Google Guava 的不變集合的數(shù)據(jù)并沒(méi)有增加。這是兩者最大的區(qū)別。那這兩者底層分別是如何實(shí)現(xiàn)不變的呢?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-504982.html

到了這里,關(guān)于【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】82 | 開(kāi)源實(shí)戰(zhàn)三(中):剖析Google Guava中用到的幾種設(shè)計(jì)模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Google 開(kāi)源庫(kù)Guava詳解

    Guava 是一組來(lái)自Google的核心Java庫(kù),包括新的集合類型(如多映射和多集)、不可變集合、圖庫(kù)和并發(fā)、I/O、哈希、原語(yǔ)、字符串等實(shí)用程序!它廣泛用于Google中的大多數(shù)Java項(xiàng)目,也被許多其他公司廣泛使用。 Guava?開(kāi)發(fā)要求?: JRE風(fēng)格需要JDK 1.8或更高版本。 如果您需要支持

    2024年02月09日
    瀏覽(31)
  • 3D項(xiàng)目中用到的一些算法

    判斷點(diǎn)是否在多邊形內(nèi)部(冬奧) (1)面積和判別法:判斷目標(biāo)點(diǎn)與多邊形的每條邊組成的三角形面積和是否等于該多邊形,相等則在多邊形內(nèi)部。 (2)夾角和判別法:判斷目標(biāo)點(diǎn)與所有邊的夾角和是否為360度,為360度則在多邊形內(nèi)部。 (3)引射線法:從目標(biāo)點(diǎn)出發(fā)引一

    2024年02月08日
    瀏覽(19)
  • 收集項(xiàng)目中用到的工具函數(shù)

    收集項(xiàng)目中常用的工具函數(shù),以備后用,使用 TS 編寫(xiě)。 document.execCommand 已被棄用,但是想要兼容微信瀏覽器、兼容 IOS 設(shè)備還不得不使用它。`。 還有一個(gè)兼容性問(wèn)題,在微信瀏覽器中,IOS 設(shè)備如果想要復(fù)制到剪切板,需要有一個(gè)點(diǎn)擊操作,比如點(diǎn)擊一個(gè)按鈕。再將一個(gè)需要

    2024年02月01日
    瀏覽(23)
  • Google 開(kāi)源庫(kù)Guava詳解(集合工具類)—Maps、Multisets、Multimaps

    Maps有許多很酷的實(shí)用程序,值得單獨(dú)解釋。 Maps.uniqueIndex(Iterable,F(xiàn)unction)解決了一個(gè)常見(jiàn)的情況,即有一堆對(duì)象,每個(gè)對(duì)象都有一些唯一的屬性,并希望能夠根據(jù)該屬性查找這些對(duì)象。 假設(shè)我們有一堆字符串,我們知道它們有唯一的長(zhǎng)度,我們希望能夠查找具有特定長(zhǎng)度

    2024年02月03日
    瀏覽(27)
  • 【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】77 | 開(kāi)源實(shí)戰(zhàn)一(下):通過(guò)剖析Java JDK源碼學(xué)習(xí)靈活應(yīng)用設(shè)計(jì)模式

    上一節(jié)課,我們講解了工廠模式、建造者模式、裝飾器模式、適配器模式在 Java JDK 中的應(yīng)用,其中,Calendar 類用到了工廠模式和建造者模式,Collections 類用到了裝飾器模式、適配器模式。學(xué)習(xí)的重點(diǎn)是讓你了解,在真實(shí)的項(xiàng)目中模式的實(shí)現(xiàn)和應(yīng)用更加靈活、多變,會(huì)根據(jù)具體

    2024年02月11日
    瀏覽(30)
  • 【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】84 | 開(kāi)源實(shí)戰(zhàn)四(上):剖析Spring框架中蘊(yùn)含的經(jīng)典設(shè)計(jì)思想或原則

    【開(kāi)源與項(xiàng)目實(shí)戰(zhàn):開(kāi)源實(shí)戰(zhàn)】84 | 開(kāi)源實(shí)戰(zhàn)四(上):剖析Spring框架中蘊(yùn)含的經(jīng)典設(shè)計(jì)思想或原則

    在 Java 世界里,Spring 框架已經(jīng)幾乎成為項(xiàng)目開(kāi)發(fā)的必備框架。作為如此優(yōu)秀和受歡迎的開(kāi)源項(xiàng)目,它是我們?cè)创a閱讀的首選材料之一,不管是設(shè)計(jì)思想,還是代碼實(shí)現(xiàn),都有很多值得我們學(xué)習(xí)的地方。接下來(lái),我們就詳細(xì)講講 Spring 框架中蘊(yùn)含的設(shè)計(jì)思想、原則和模式。因?yàn)?/p>

    2024年02月12日
    瀏覽(14)
  • 【總目錄】機(jī)器學(xué)習(xí)原理剖析、開(kāi)源實(shí)戰(zhàn)項(xiàng)目、全套學(xué)習(xí)指南(50篇合集)

    【總目錄】機(jī)器學(xué)習(xí)原理剖析、開(kāi)源實(shí)戰(zhàn)項(xiàng)目、全套學(xué)習(xí)指南(50篇合集)

    我為了更加的高效的學(xué)習(xí),需要不斷地輸入和輸出 相信不管此時(shí)的你是懷著好奇心打開(kāi)這篇文章;還是偶然間刷到這篇博文;或者帶有學(xué)習(xí)目的性走到這片領(lǐng)域,我都相信,面前的你一定會(huì)成功,因?yàn)槟愣猛顿Y和學(xué)習(xí)。學(xué)習(xí)是一個(gè)不斷發(fā)展的過(guò)程,我們要用聯(lián)系的眼光看待

    2023年04月08日
    瀏覽(15)
  • 深入剖析gRPC:Google開(kāi)源的高性能RPC框架

    在本篇文章中,我們將深入剖析gRPC,Google開(kāi)源的高性能RPC框架。gRPC是一種基于HTTP/2的高性能、可擴(kuò)展的RPC框架,它使用Protocol Buffers作為接口定義語(yǔ)言,可以在多種編程語(yǔ)言之間實(shí)現(xiàn)無(wú)縫通信。 gRPC的核心設(shè)計(jì)理念是:通過(guò)使用HTTP/2作為傳輸協(xié)議,實(shí)現(xiàn)高效、可擴(kuò)展的RPC通信

    2024年02月19日
    瀏覽(28)
  • git常見(jiàn)使用 --實(shí)習(xí)中用到的

    1.正常的上傳和提交 2.git rebase 當(dāng)存在多個(gè)commit的提交節(jié)點(diǎn)時(shí),統(tǒng)一成一次提交。 3.版本回退 git reset --hard :把head指向之前的某次提交。hard是強(qiáng)制回退,不保存中間提交的內(nèi)容。 git revert -n 版本號(hào) : 不會(huì)丟失現(xiàn)有版本的提交記錄,生成一個(gè)新版本 4.查看分支+切換分支 git b

    2024年02月07日
    瀏覽(20)
  • 多媒體工作中用到的小工具

    多媒體工作中用到的小工具

    安利下嵌入式多媒體用到的各種小工具 下面是同事們推薦的 以下是對(duì)這些軟件的簡(jiǎn)要介紹: ocenaudio :ocenaudio是一款跨平臺(tái)的音頻編輯軟件,它提供了直觀的界面和豐富的功能,可以幫助用戶進(jìn)行音頻剪輯、修復(fù)、轉(zhuǎn)碼等操作。 MKVToolNix :MKVToolNix是一款開(kāi)源的多媒體容器格

    2024年02月15日
    瀏覽(85)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包