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

一文帶你了解Java設(shè)計(jì)模式之原型模式

 更新時(shí)間:2022年09月04日 10:09:39   作者:小小張自由—>張有博  
原型模式其實(shí)就是從一個(gè)對(duì)象在創(chuàng)建另外一個(gè)可定制的對(duì)象,不需要知道任何創(chuàng)建的細(xì)節(jié)。本文就來通過示例為大家詳細(xì)聊聊原型模式,需要的可以參考一下

定義

用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。

原型模式其實(shí)就是從一個(gè)對(duì)象在創(chuàng)建另外一個(gè)可定制的對(duì)象,不需要知道任何創(chuàng)建的細(xì)節(jié)

解決的問題

在運(yùn)行期建立和刪除原型。

經(jīng)常用于:

類初始化消耗資源較多

構(gòu)造函數(shù)比較復(fù)雜

核心要點(diǎn)

1.實(shí)現(xiàn)cloneable 接口,重寫Object的clone方法

2.利用已有的一個(gè)原型對(duì)象,快速地生成和原型對(duì)象一樣的實(shí)例。

類圖

淺復(fù)制與深復(fù)制的區(qū)別

淺復(fù)制:基本數(shù)據(jù)類型進(jìn)行值傳遞、引用數(shù)據(jù)類型的指針仍是指向原來的對(duì)象(成員變量)。

深復(fù)制:基本數(shù)據(jù)類型進(jìn)行值傳遞、引用數(shù)據(jù)類型開辟新的內(nèi)存空間。

代碼實(shí)現(xiàn)

需求:實(shí)現(xiàn)克隆羊

有一頭羊,需要經(jīng)過賦值再克隆出兩頭。

未使用設(shè)計(jì)模式

/**
 * 克隆羊類
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 14:51
 */
public class Sheep {

    private String name;

    private Integer age;

    private String color;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Sheep() {
    }

    public Sheep(String name, Integer age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }
}

Main方法

/**
 * 
 * 傳統(tǒng)模式
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 14:47
 */
public class Client {

    public static void main(String[] args) {
        //小羊
        Sheep sheep=new Sheep("小紅",8,"紅色");
        //克隆羊
        Sheep sheep2=sheep;
        Sheep sheep3=sheep;

        System.out.println("通過賦值,指針還是指向sheep");
        System.out.println(sheep);
        System.out.println(sheep2);
        System.out.println(sheep3);
        
    }

}

//通過賦值,指針還是指向sheep
//com.promsing.creational.prototype.type1.Sheep@1b6d3586
//com.promsing.creational.prototype.type1.Sheep@1b6d3586
//com.promsing.creational.prototype.type1.Sheep@1b6d3586

實(shí)現(xiàn)Cloneable接口

Cloneable是標(biāo)記型的接口,它們內(nèi)部都沒有方法和屬性,實(shí)現(xiàn) Cloneable來表示該對(duì)象能被克隆,能使用Object.clone()方法。

如果沒有實(shí)現(xiàn) Cloneable的類對(duì)象調(diào)用clone()就會(huì)拋出CloneNotSupportedException。

實(shí)現(xiàn)Cloneable默認(rèn)是淺復(fù)制

/**
 * 克隆羊
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 14:53
 */
public class Sheep implements Cloneable {

    private String name;

    private Integer age;

    private String color;

    /**
     * 羊的朋友
     */
    private Sheep friend;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Sheep() {
    }

    public Sheep getFriend() {
        return friend;
    }

    public void setFriend(Sheep friend) {
        this.friend = friend;
    }

    public Sheep(String name, Integer age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }


    /**
     * 克隆該實(shí)例,調(diào)用object.clone的方法
     * @return
     */
    @Override
    protected Sheep clone() {

        Sheep sheep = null;
        try {
            sheep = (Sheep) super.clone();

        } catch (CloneNotSupportedException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return sheep;
    }
}

Main方法

/**
 * 淺復(fù)制:淺復(fù)制:基本數(shù)據(jù)類型進(jìn)行值傳遞、引用數(shù)據(jù)類型的指針仍是指向原來的對(duì)象(成員變量)。
 */
public class ShallowClient {

    public static void main(String[] args) {

        Sheep sheep=new Sheep("小紅",9,"紅色");
        sheep.setFriend(new Sheep("小黑",10,"黑色"));
        Sheep sheep1 = sheep.clone();//開辟了新的空間
        Sheep sheep2 = sheep.clone();

        //淺復(fù)制
        System.out.println("原型羊"+sheep);
        System.out.println("克隆羊"+sheep1+"-朋友羊-"+sheep1.getFriend());
        System.out.println("克隆羊"+sheep2+"-朋友羊-"+sheep2.getFriend());
        
//原型羊com.promsing.creational.prototype.type3.Sheep@1b6d3586
//克隆羊com.promsing.creational.prototype.type3.Sheep@4554617c-朋友羊-com.promsing.creational.prototype.type3.Sheep@74a14482
//克隆羊com.promsing.creational.prototype.type3.Sheep@1540e19d-朋友羊-com.promsing.creational.prototype.type3.Sheep@74a14482


    }

}

一定要實(shí)現(xiàn)接口cloneable 否則報(bào)錯(cuò):

Exception in thread "main" java.lang.CloneNotSupportedException: com.promsing.creational.prototype.type4.Sheep
    at java.lang.Object.clone(Native Method)
    at com.promsing.creational.prototype.type4.Sheep.clone(Sheep.java:76)
    at com.promsing.creational.prototype.type4.DeepClient.main(DeepClient.java:14)

深復(fù)制-重寫clone

羊類、房子類都需要實(shí)現(xiàn)Cloneable接口

房子類

/**
 * 房子類
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 15:27
 */
public class House implements Cloneable {

    //地址
    private String address;

    //尺寸
    private Integer size;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
    }


    /**
     * 克隆的方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

羊類

/**
 * 克隆羊-深拷貝
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 15:26
 */
public class Sheep implements  Cloneable {

    private String name;

    private Integer age;

    private String color;

    /**
     * 羊的房子:引用類型
     */
    private House house;

    public House getHouse() {
        return house;
    }

    public void setHouse(House house) {
        this.house = house;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Sheep() {
    }


    public Sheep(String name, Integer age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    /**
     * 克隆該實(shí)例,調(diào)用object,clone的方法
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {

        //對(duì)基本數(shù)據(jù)類型進(jìn)行處理
        Sheep deep = null;
        deep = (Sheep) super.clone();

        //對(duì)引用類型進(jìn)行處理
        //進(jìn)行再次克隆
        House clone = (House) deep.getHouse().clone();
        deep.setHouse(clone);

        return deep;
    }

   
}

Main

/**
 * 深復(fù)制:羊類、房子類都需要重寫clone的接口,比較麻煩。不符合開閉
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 15:38
 */
public class DeepClient {

    public static void main(String[] args) throws CloneNotSupportedException {
        Sheep sheep=new Sheep("黑",90,"heisee");
        sheep.setHouse(new House());
        Sheep clone = (Sheep)sheep.clone();
        System.out.println("原本的對(duì)象");
        System.out.println(sheep);
        System.out.println(sheep.getHouse());
        System.out.println("克隆的對(duì)象");
        System.out.println(clone);
        System.out.println(clone.getHouse());
        
        
        //開辟了新的內(nèi)存空間
        //原本的對(duì)象
        //com.promsing.creational.prototype.type4.Sheep@1b6d3586
        //com.promsing.creational.prototype.type4.House@4554617c
        //克隆的對(duì)象
        //com.promsing.creational.prototype.type4.Sheep@74a14482
        //com.promsing.creational.prototype.type4.House@1540e19d
    }

}

深復(fù)制-通過對(duì)象序列化實(shí)現(xiàn)(推薦)

羊類、房子類都需要實(shí)現(xiàn)Serializable接口。注意這里可以不實(shí)現(xiàn)Cloneable了。

房子類

/**
 * 房子類
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 15:27
 */
public class House implements Serializable{

    //地址
    private String address;

    //尺寸
    private Integer size;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
    }

}

羊類

/**
 * 克隆羊-深拷貝
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 15:26
 */
public class Sheep implements Serializable {

    private String name;

    private Integer age;

    private String color;

    /**
     * 羊的房子:引用類型
     */
    private House house;

    public House getHouse() {
        return house;
    }

    public void setHouse(House house) {
        this.house = house;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Sheep() {
    }


    public Sheep(String name, Integer age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

 
    /**
     * 序列化的方式:進(jìn)行深復(fù)制
     * 寫著麻煩:用著簡單。支持開閉原則
     * @return
     */
    public Object deepClone() {

        //創(chuàng)建流對(duì)象
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        try {

            //序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this); //當(dāng)前這個(gè)對(duì)象以對(duì)象流的方式輸出

            //反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            Sheep copyObj = (Sheep) ois.readObject();

            return copyObj;

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return null;
        } finally {
            //關(guān)閉流
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (Exception e2) {
                // TODO: handle exception
                System.out.println(e2.getMessage());
            }
        }

    }
}

Main

/**
 * 深復(fù)制
 *
 * @author Promsing(張有博)
 * @version 1.0.0
 * @since 2022/9/3 - 15:38
 */
public class DeepClient {

    public static void main(String[] args) throws CloneNotSupportedException {
        Sheep sheep=new Sheep("黑",90,"heisee");
        sheep.setHouse(new House());
        Sheep clone = (Sheep)sheep.deepClone();
        System.out.println("原本的對(duì)象");
        System.out.println(sheep);
        System.out.println(sheep.getHouse());
        System.out.println("克隆的對(duì)象");
        System.out.println(clone);
        System.out.println(clone.getHouse());
    }

}

拓展

Spring使用原型模式:@scope(“prototype”)

public static void main(String[] args) throws IOException {
      //new一個(gè)容器
    AnnotationConfigWebApplicationContext context =
        new AnnotationConfigWebApplicationContext();
    System.out.println("run success");

    OrderService bean = context.getBean(OrderService.class);
}

//根據(jù)getBean點(diǎn)進(jìn)去
public <T> T getBean(Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(requiredType);
}

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
}

后續(xù)走到了。AbstractBeanFactory類中的doGetBean方法中里邊代碼做判斷mbd.isPrototype()

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			//代碼省略~~~~
		}

		else {
			//代碼省略~~~~

			
			try {
				//代碼省略~~~~
                
				// Create bean instance.
                //判斷是否是單例
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                //判斷是否是多例(原型)
                //這里會(huì)創(chuàng)建一個(gè)新的對(duì)象
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					//代碼省略~~~~
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		//代碼省略~~~~
		}
		return (T) bean;
	}

ArrayList實(shí)現(xiàn)了Cloneable接口

public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}

到此這篇關(guān)于一文帶你了解Java設(shè)計(jì)模式之原型模式的文章就介紹到這了,更多相關(guān)Java原型模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot的@ControllerAdvice處理全局異常詳解

    SpringBoot的@ControllerAdvice處理全局異常詳解

    這篇文章主要介紹了SpringBoot的@ControllerAdvice處理全局異常詳解,但有時(shí)卻往往會(huì)產(chǎn)生一些bug,這時(shí)候就破壞了返回?cái)?shù)據(jù)的一致性,導(dǎo)致調(diào)用者無法解析,所以我們常常會(huì)定義一個(gè)全局的異常攔截器,需要的朋友可以參考下
    2024-01-01
  • Java中如何將?int[]?數(shù)組轉(zhuǎn)換為?ArrayList(list)

    Java中如何將?int[]?數(shù)組轉(zhuǎn)換為?ArrayList(list)

    這篇文章主要介紹了Java中將?int[]?數(shù)組?轉(zhuǎn)換為?List(ArrayList),本文通過示例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • Java定時(shí)任務(wù)取消的示例代碼

    Java定時(shí)任務(wù)取消的示例代碼

    java定時(shí)任務(wù)如何取消,并比如,我之前想每周二晚上6點(diǎn)自動(dòng)生成一條devops流水線,現(xiàn)在我想停掉,下面給大家分享java定時(shí)任務(wù)取消的示例代碼,演示如何創(chuàng)建一個(gè)每周二晚上6點(diǎn)自動(dòng)生成一條devops流水線的定時(shí)任務(wù),感興趣的朋友一起看看吧
    2024-02-02
  • java 實(shí)現(xiàn)音樂播放器的簡單實(shí)例

    java 實(shí)現(xiàn)音樂播放器的簡單實(shí)例

    這篇文章主要介紹了java 實(shí)現(xiàn)音樂播放器的簡單實(shí)例的相關(guān)資料,希望通過本文能幫助到大家,實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下
    2017-09-09
  • SpringBoot中集成screw(螺絲釘)實(shí)現(xiàn)數(shù)據(jù)庫表結(jié)構(gòu)文檔生成方法

    SpringBoot中集成screw(螺絲釘)實(shí)現(xiàn)數(shù)據(jù)庫表結(jié)構(gòu)文檔生成方法

    這篇文章主要介紹了SpringBoot中集成screw(螺絲釘)實(shí)現(xiàn)數(shù)據(jù)庫表結(jié)構(gòu)文檔生成,下面以連接mysql數(shù)據(jù)庫并生成html格式的數(shù)據(jù)庫結(jié)構(gòu)文檔為例,插件的使用方式除可以使用代碼外,還可以使用Maven插件的方式,需要的朋友可以參考下
    2024-07-07
  • Java判斷本機(jī)IP地址類型的方法

    Java判斷本機(jī)IP地址類型的方法

    Java判斷本機(jī)IP地址類型的方法,需要的朋友可以參考一下
    2013-03-03
  • idea 在springboot中使用lombok插件的方法

    idea 在springboot中使用lombok插件的方法

    這篇文章主要介紹了idea 在springboot中使用lombok的相關(guān)資料,通過代碼給大家介紹在pom.xml中引入依賴的方法,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • MyBatis的mapper.xml文件中入?yún)⒑头祷刂档膶?shí)現(xiàn)

    MyBatis的mapper.xml文件中入?yún)⒑头祷刂档膶?shí)現(xiàn)

    這篇文章主要介紹了MyBatis的mapper.xml文件中入?yún)⒑头祷刂档膶?shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • MyBatis中#和$的區(qū)別小結(jié)

    MyBatis中#和$的區(qū)別小結(jié)

    ${} 和 #{} 都是 MyBatis 中用來替換參數(shù)的,它們都可以將用戶傳遞過來的參數(shù),替換到 MyBatis 最終生成的 SQL 中,但它們區(qū)別卻是很大的,接下來我們一起來看
    2023-09-09
  • MyBatis Generator介紹及使用方法

    MyBatis Generator介紹及使用方法

    MyBatis Generator 是一款針對(duì) MyBatis 或 iBATIS 設(shè)計(jì)的代碼生成器,由 MyBatis 官方提供,這篇文章主要介紹了MyBatis Generator介紹及使用方法,需要的朋友可以參考下
    2023-06-06

最新評(píng)論

黑山县| 松滋市| 安溪县| 遂宁市| 三原县| 临清市| 长宁县| 子洲县| 镇远县| 彭州市| 中牟县| 广东省| 杭州市| 巩义市| 深州市| 达拉特旗| 光山县| 三门峡市| 贵溪市| 樟树市| 永定县| 南开区| 临沧市| 安庆市| 长葛市| 麦盖提县| 祁东县| 右玉县| 秦皇岛市| 和田市| 深圳市| 安泽县| 湘乡市| 荔波县| 墨江| 恩平市| 富锦市| 大英县| 洛南县| 丰台区| 龙陵县|