最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

5種Java經(jīng)典創(chuàng)建型模式詳解

 更新時(shí)間:2016年03月08日 15:53:17   作者:第八號(hào)當(dāng)鋪  
這篇文章主要為大家詳細(xì)介紹了5種Java經(jīng)典創(chuàng)建型模式,感興趣的小伙伴們可以參考一下

一、概況

總體來(lái)說(shuō)設(shè)計(jì)模式分為三大類:

(1)創(chuàng)建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

(2)結(jié)構(gòu)型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

(3)行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責(zé)任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問者模式、中介者模式、解釋器模式。

二、設(shè)計(jì)模式的六大原則

1、開閉原則(Open Close Principle)

開閉原則就是說(shuō)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。在程序需要進(jìn)行拓展的時(shí)候,不能去修改原有的代碼,實(shí)現(xiàn)一個(gè)熱插拔的效果。

2、里氏代換原則(Liskov Substitution Principle)

其官方描述比較抽象,可自行百度。實(shí)際上可以這樣理解:(1)子類的能力必須大于等于父類,即父類可以使用的方法,子類都可以使用。(2)返回值也是同樣的道理。假設(shè)一個(gè)父類方法返回一個(gè)List,子類返回一個(gè)ArrayList,這當(dāng)然可以。如果父類方法返回一個(gè)ArrayList,子類返回一個(gè)List,就說(shuō)不通了。這里子類返回值的能力是比父類小的。(3)還有拋出異常的情況。任何子類方法可以聲明拋出父類方法聲明異常的子類。
而不能聲明拋出父類沒有聲明的異常。

3、依賴倒轉(zhuǎn)原則(Dependence Inversion Principle)

這個(gè)是開閉原則的基礎(chǔ),具體內(nèi)容:面向接口編程,依賴于抽象而不依賴于具體。

4、接口隔離原則(Interface Segregation Principle)

這個(gè)原則的意思是:使用多個(gè)隔離的接口,比使用單個(gè)接口要好。還是一個(gè)降低類之間的耦合度的意思,從這兒我們看出,其實(shí)設(shè)計(jì)模式就是一個(gè)軟件的設(shè)計(jì)思想,從大型軟件架構(gòu)出發(fā),為了升級(jí)和維護(hù)方便。所以上文中多次出現(xiàn):降低依賴,降低耦合。

5、迪米特法則(最少知道原則)(Demeter Principle)

為什么叫最少知道原則,就是說(shuō):一個(gè)實(shí)體應(yīng)當(dāng)盡量少的與其他實(shí)體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對(duì)獨(dú)立。

6、合成復(fù)用原則(Composite Reuse Principle)

原則是盡量使用合成/聚合的方式,而不是使用繼承。

三、創(chuàng)建型模式

創(chuàng)建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

3.1、工廠方法模式

工廠方法模式分為三種:普通工廠模式、多個(gè)工廠方法模式和靜態(tài)工廠方法模式。

3.1.1、普通工廠模式

普通工廠模式就是建立一個(gè)工廠類,對(duì)實(shí)現(xiàn)了同一接口的一些類進(jìn)行實(shí)例的創(chuàng)建。

package com.mode.create;
 
public interface MyInterface {
  public void print();
}
package com.mode.create;
 
public class MyClassOne implements MyInterface {
 
  @Override
  public void print() {
    System.out.println("MyClassOne");
  }
 
}

package com.mode.create;
 
public class MyClassTwo implements MyInterface {
 
  @Override
  public void print() {
    System.out.println("MyClassTwo");
  }
 
}

package com.mode.create;
 
public class MyFactory {
 
  public MyInterface produce(String type) { 
    if ("One".equals(type)) { 
      return new MyClassOne(); 
    } else if ("Two".equals(type)) { 
      return new MyClassTwo(); 
    } else { 
      System.out.println("沒有要找的類型"); 
      return null; 
    } 
  }
 
}

package com.mode.create;
 
public class FactoryTest {
 
  public static void main(String[] args){
    MyFactory factory = new MyFactory(); 
    MyInterface myi = factory.produce("One"); 
    myi.print();
  }
 
}

FactoryTest的運(yùn)行結(jié)果我想應(yīng)該很明顯了。

再回頭來(lái)理解這句話:普通工廠模式就是建立一個(gè)工廠類,對(duì)實(shí)現(xiàn)了同一接口的一些類進(jìn)行實(shí)例的創(chuàng)建。

3.1.2、多個(gè)工廠方法模式

多個(gè)工廠方法模式,是對(duì)普通工廠方法模式的改進(jìn),多個(gè)工廠方法模式就是提供多個(gè)工廠方法,分別創(chuàng)建對(duì)象。

直接看代碼吧,我們修改MyFactory和FactoryTest如下:

package com.mode.create;
 
public class MyFactory {
 
  public MyInterface produceOne() {
    return new MyClassOne();
  }
 
  public MyInterface produceTwo() {
    return new MyClassTwo();
  }
 
}

package com.mode.create;
 
public class FactoryTest {
 
  public static void main(String[] args){
    MyFactory factory = new MyFactory(); 
    MyInterface myi = factory.produceOne();
    myi.print();
  }
 
}

運(yùn)行結(jié)果也是十分明顯了。

再回頭來(lái)理解這句話:多個(gè)工廠方法模式,是對(duì)普通工廠方法模式的改進(jìn),多個(gè)工廠方法模式就是提供多個(gè)工廠方法,分別創(chuàng)建對(duì)象。

3.1.3、靜態(tài)工廠方法模式

靜態(tài)工廠方法模式,將上面的多個(gè)工廠方法模式里的方法置為靜態(tài)的,不需要?jiǎng)?chuàng)建實(shí)例,直接調(diào)用即可。

直接看代碼吧,我們修改MyFactory和FactoryTest如下:

package com.mode.create;
 
public class MyFactory {
 
  public static MyInterface produceOne() {
    return new MyClassOne();
  }
 
  public static MyInterface produceTwo() {
    return new MyClassTwo();
  }
 
}

package com.mode.create;
 
public class FactoryTest {
 
  public static void main(String[] args){ 
    MyInterface myi = MyFactory.produceOne();
    myi.print();
  }
 
}

運(yùn)行結(jié)果依舊很明顯。

再回顧:靜態(tài)工廠方法模式,將上面的多個(gè)工廠方法模式里的方法置為靜態(tài)的,不需要?jiǎng)?chuàng)建實(shí)例,直接調(diào)用即可。

3.2、抽象工廠模式

工廠方法模式有一個(gè)問題就是,類的創(chuàng)建依賴工廠類,也就是說(shuō),如果想要拓展程序,必須對(duì)工廠類進(jìn)行修改,這違背了閉包原則。

為解決這個(gè)問題,我們來(lái)看看抽象工廠模式:創(chuàng)建多個(gè)工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼。

這樣就符合閉包原則了。

下面來(lái)看看代碼:

MyInterface、MyClassOne、MyClassTwo不變。

新增如下接口和類:

package com.mode.create;
 
public interface Provider {
  public MyInterface produce(); 
}

package com.mode.create;
 
public class MyFactoryOne implements Provider {
 
  @Override
  public MyInterface produce() {
    return new MyClassOne();
  }
 
}

package com.mode.create;
 
public class MyFactoryTwo implements Provider {
 
  @Override
  public MyInterface produce() {
    return new MyClassTwo();
  }
 
}

修改測(cè)試類FactoryTest如下:

package com.mode.create;
 
public class FactoryTest {
 
  public static void main(String[] args){ 
    Provider provider = new MyFactoryOne();
    MyInterface myi = provider.produce();
    myi.print();
  }
 
}

運(yùn)行結(jié)果依舊顯然。

再回顧:抽象工廠模式就是創(chuàng)建多個(gè)工廠類,這樣一旦需要增加新的功能,直接增加新的工廠類就可以了,不需要修改之前的代碼。

3.3、單例模式

單例模式,不需要過多的解釋。

直接看代碼吧:

package test;
 
public class MyObject {
 
  private static MyObject myObject;
 
  private MyObject() {
  }
 
  public static MyObject getInstance() {
    if (myObject != null) {
    } else {
      myObject = new MyObject();
    }
    return myObject;
  }
 
}

但是這樣會(huì)引發(fā)多線程問題,詳細(xì)解說(shuō)可以看《Java多線程編程核心技術(shù)》書中的第六章。

3.4、建造者模式

建造者模式:是將一個(gè)復(fù)雜的對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

字面看來(lái)非常抽象,實(shí)際上它也十分抽象?。。?!

建造者模式通常包括下面幾個(gè)角色:

(1) Builder:給出一個(gè)抽象接口,以規(guī)范產(chǎn)品對(duì)象的各個(gè)組成成分的建造。這個(gè)接口規(guī)定要實(shí)現(xiàn)復(fù)雜對(duì)象的哪些部分的創(chuàng)建,并不涉及具體的對(duì)象部件的創(chuàng)建。

(2) ConcreteBuilder:實(shí)現(xiàn)Builder接口,針對(duì)不同的商業(yè)邏輯,具體化復(fù)雜對(duì)象的各部分的創(chuàng)建。 在建造過程完成后,提供產(chǎn)品的實(shí)例。

(3)Director:調(diào)用具體建造者來(lái)創(chuàng)建復(fù)雜對(duì)象的各個(gè)部分,在指導(dǎo)者中不涉及具體產(chǎn)品的信息,只負(fù)責(zé)保證對(duì)象各部分完整創(chuàng)建或按某種順序創(chuàng)建。

(4)Product:要?jiǎng)?chuàng)建的復(fù)雜對(duì)象。

在游戲開發(fā)中建造小人是經(jīng)常的事了,要求是:小人必須包括頭,身體和腳。

下面我們看看如下代碼:

Product(要?jiǎng)?chuàng)建的復(fù)雜對(duì)象。):

package com.mode.create;
 
public class Person {
 
  private String head;
  private String body;
  private String foot;
 
  public String getHead() {
    return head;
  }
 
  public void setHead(String head) {
    this.head = head;
  }
 
  public String getBody() {
    return body;
  }
 
  public void setBody(String body) {
    this.body = body;
  }
 
  public String getFoot() {
    return foot;
  }
 
  public void setFoot(String foot) {
    this.foot = foot;
  }
}

Builder(給出一個(gè)抽象接口,以規(guī)范產(chǎn)品對(duì)象的各個(gè)組成成分的建造。這個(gè)接口規(guī)定要實(shí)現(xiàn)復(fù)雜對(duì)象的哪些部分的創(chuàng)建,并不涉及具體的對(duì)象部件的創(chuàng)建。):

package com.mode.create;
 
public interface PersonBuilder {
  void buildHead();
  void buildBody();
  void buildFoot();
  Person buildPerson();
}

ConcreteBuilder(實(shí)現(xiàn)Builder接口,針對(duì)不同的商業(yè)邏輯,具體化復(fù)雜對(duì)象的各部分的創(chuàng)建。 在建造過程完成后,提供產(chǎn)品的實(shí)例。):

package com.mode.create;
 
public class ManBuilder implements PersonBuilder {
 
  Person person;
 
  public ManBuilder() {
    person = new Person();
  }
 
  public void buildBody() {
    person.setBody("建造男人的身體");
  }
 
  public void buildFoot() {
    person.setFoot("建造男人的腳");
  }
 
  public void buildHead() {
    person.setHead("建造男人的頭");
  }
 
  public Person buildPerson() {
    return person;
  }
 
}

Director(調(diào)用具體建造者來(lái)創(chuàng)建復(fù)雜對(duì)象的各個(gè)部分,在指導(dǎo)者中不涉及具體產(chǎn)品的信息,只負(fù)責(zé)保證對(duì)象各部分完整創(chuàng)建或按某種順序創(chuàng)建。):

package com.mode.create;
 
public class PersonDirector {
  public Person constructPerson(PersonBuilder pb) {
    pb.buildHead();
    pb.buildBody();
    pb.buildFoot();
    return pb.buildPerson();
  }
}

測(cè)試類:

package com.mode.create;
 
public class Test {
  public static void main(String[] args) {
    PersonDirector pd = new PersonDirector();
    Person person = pd.constructPerson(new ManBuilder());
    System.out.println(person.getBody());
    System.out.println(person.getFoot());
    System.out.println(person.getHead());
  }
}

運(yùn)行結(jié)果:

回顧:建造者模式:是將一個(gè)復(fù)雜的對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。

3.5、原型模式

該模式的思想就是將一個(gè)對(duì)象作為原型,對(duì)其進(jìn)行復(fù)制、克隆,產(chǎn)生一個(gè)和原對(duì)象類似的新對(duì)象。

說(shuō)道復(fù)制對(duì)象,我將結(jié)合對(duì)象的淺復(fù)制和深復(fù)制來(lái)說(shuō)一下,首先需要了解對(duì)象深、淺復(fù)制的概念:

淺復(fù)制:將一個(gè)對(duì)象復(fù)制后,基本數(shù)據(jù)類型的變量都會(huì)重新創(chuàng)建,而引用類型,指向的還是原對(duì)象所指向的。

深復(fù)制:將一個(gè)對(duì)象復(fù)制后,不論是基本數(shù)據(jù)類型還有引用類型,都是重新創(chuàng)建的。簡(jiǎn)單來(lái)說(shuō),就是深復(fù)制進(jìn)行了完全徹底的復(fù)制,而淺復(fù)制不徹底。

寫一個(gè)深淺復(fù)制的例子:

package com.mode.create;
 
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
public class Prototype implements Cloneable, Serializable {
 
  private static final long serialVersionUID = 1L;
 
  private int base;
 
  private Integer obj;
 
   /* 淺復(fù)制 */ 
  public Object clone() throws CloneNotSupportedException {
    // 因?yàn)镃loneable接口是個(gè)空接口,你可以任意定義實(shí)現(xiàn)類的方法名
    // 如cloneA或者cloneB,因?yàn)榇颂幍闹攸c(diǎn)是super.clone()這句話
    // super.clone()調(diào)用的是Object的clone()方法
    // 而在Object類中,clone()是native(本地方法)的
    Prototype proto = (Prototype) super.clone();
    return proto;
  }
 
  /* 深復(fù)制 */
  public Object deepClone() throws IOException, ClassNotFoundException {
 
    /* 寫入當(dāng)前對(duì)象的二進(jìn)制流 */
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(this);
 
    /* 讀出二進(jìn)制流產(chǎn)生的新對(duì)象 */
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return ois.readObject();
  }
 
  public int getBase() {
    return base;
  }
 
  public void setBase(int base) {
    this.base = base;
  }
 
  public Integer getObj() {
    return obj;
  }
 
  public void setObj(Integer obj) {
    this.obj = obj;
  }
 
}

測(cè)試類:

package com.mode.create;
 
import java.io.IOException;
 
public class Test {
  public static void main(String[] args) throws CloneNotSupportedException,
      ClassNotFoundException, IOException {
    Prototype prototype = new Prototype();
    prototype.setBase(1);
    prototype.setObj(new Integer(2));
    /* 淺復(fù)制 */ 
    Prototype prototype1 = (Prototype) prototype.clone();
    /* 深復(fù)制 */
    Prototype prototype2 = (Prototype) prototype.deepClone();
    System.out.println(prototype1.getObj()==prototype1.getObj());
    System.out.println(prototype1.getObj()==prototype2.getObj());
  }
}

運(yùn)行結(jié)果:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • 詳解JSON與?Java對(duì)象之間的轉(zhuǎn)化

    詳解JSON與?Java對(duì)象之間的轉(zhuǎn)化

    在現(xiàn)在的日常開發(fā)中,不管前端還是后端,JSON?格式的數(shù)據(jù)是用得比較多的,甚至可以說(shuō)無(wú)處不在。所以本文主要來(lái)講講JSON?格式的數(shù)據(jù)與?Java?對(duì)象之間的轉(zhuǎn)化吧
    2023-03-03
  • 如何修改FeginCilent定義的服務(wù)名到指定服務(wù)

    如何修改FeginCilent定義的服務(wù)名到指定服務(wù)

    這篇文章主要介紹了修改FeginCilent定義的服務(wù)名到指定服務(wù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Maven 搭建SpringMVC+Hibernate項(xiàng)目詳解

    Maven 搭建SpringMVC+Hibernate項(xiàng)目詳解

    本文主要介紹Maven 搭建SpringMVC+Hibernate的知識(shí),這里整理了詳細(xì)的資料,并附示例代碼,有興趣的小伙伴可以參考下
    2016-09-09
  • 通過反射注解批量插入數(shù)據(jù)到DB的實(shí)現(xiàn)方法

    通過反射注解批量插入數(shù)據(jù)到DB的實(shí)現(xiàn)方法

    今天小編就為大家分享一篇關(guān)于通過反射注解批量插入數(shù)據(jù)到DB的實(shí)現(xiàn)方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-03-03
  • Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解

    Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解

    這篇文章主要介紹了Java計(jì)算數(shù)學(xué)表達(dá)式代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • java8日期工具類封裝的實(shí)戰(zhàn)記錄

    java8日期工具類封裝的實(shí)戰(zhàn)記錄

    java time包中的是類是不可變且線程安全的,新的時(shí)間及日期API位于java.time中,下面這篇文章主要給大家介紹了關(guān)于java8日期工具類封裝的相關(guān)資料,需要的朋友可以參考下
    2021-09-09
  • Apache?Maven3.6.0的下載安裝和環(huán)境配置(圖文教程)

    Apache?Maven3.6.0的下載安裝和環(huán)境配置(圖文教程)

    本文主要介紹了Apache?Maven3.6.0的下載安裝和環(huán)境配置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java中多態(tài)的實(shí)現(xiàn)原理詳細(xì)解析

    Java中多態(tài)的實(shí)現(xiàn)原理詳細(xì)解析

    這篇文章主要介紹了Java中多態(tài)的實(shí)現(xiàn)原理詳細(xì)解析,多態(tài)是面向?qū)ο缶幊陶Z(yǔ)言的重要特性,它允許基類的指針或引用指向派生類的對(duì)象,而在具體訪問時(shí)實(shí)現(xiàn)方法的動(dòng)態(tài)綁定,需要的朋友可以參考下
    2024-01-01
  • SpringBoot自動(dòng)配置特點(diǎn)與原理詳細(xì)分析

    SpringBoot自動(dòng)配置特點(diǎn)與原理詳細(xì)分析

    這篇文章主要介紹了SpringBoot自動(dòng)配置原理分析,SpringBoot是我們經(jīng)常使用的框架,那么你能不能針對(duì)SpringBoot實(shí)現(xiàn)自動(dòng)配置做一個(gè)詳細(xì)的介紹。如果可以的話,能不能畫一下實(shí)現(xiàn)自動(dòng)配置的流程圖。牽扯到哪些關(guān)鍵類,以及哪些關(guān)鍵點(diǎn)
    2022-08-08
  • 解決IDEA中不能正常輸入光標(biāo)變粗的問題

    解決IDEA中不能正常輸入光標(biāo)變粗的問題

    這篇文章主要介紹了在IDEA中不能正常輸入光標(biāo)變粗的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-09-09

最新評(píng)論

陵川县| 桐梓县| 神农架林区| 资兴市| 巴林左旗| 新邵县| 卓尼县| 无为县| 寿阳县| 抚州市| 青河县| 镶黄旗| 盘山县| 多伦县| 青州市| 仲巴县| 横峰县| 桐柏县| 石城县| 思茅市| 星子县| 墨竹工卡县| 沅陵县| 黔江区| 德庆县| 漯河市| 调兵山市| 鄂尔多斯市| 武陟县| 玉环县| 剑阁县| 汉中市| 乡宁县| 惠安县| 丽江市| 南投县| 乌海市| 东宁县| 南江县| 交口县| 内江市|