设计模式--原型模式

原文参考:https://blog.csdn.net/chenliguan/article/details/69855738

 

原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节,UML图为:

 

首先说浅复制,被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。

举例:书作为一个原型,包含题目和内容两个属性

package com.designmodel.prototype;

import java.util.ArrayList;

public class Book implements Cloneable {

    private String title;
    private ArrayList<String> image = new ArrayList<String>();
    
    public Book() {
        
    }

    @Override
    protected Book clone() {
        try {
            Book book = (Book) super.clone();
            return book;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        
        return null;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public ArrayList<String> getImage() {
        return image;
    }

    public void setImage(ArrayList<String> image) {
        this.image = image;
    }
    
    public void addImage(String newImage) {
        this.image.add(newImage);
    }
    
    public void showBook() {
        System.out.println("title:" + title);
        for (String img : image) {
            System.out.println("image name:" + img);
        }

    }
    
}

在客户端调用时,book1的内容是“王子和公主”,在book2中又添加“小丑和精灵”,根据结果可以看出,book1和book2都指向同一个引用,即再回来看book1的内容时,添加了book2的内容

package com.designmodel.prototype;

import java.util.ArrayList;

public class Client {

    public static void main(String[] args) {
        Book book1 = new Book();
        book1.setTitle("1001夜");
        ArrayList<String> images = new ArrayList<String>();
        images.add("王子和公主");
        book1.setImage(images);
        book1.showBook();
        
        System.out.println("--About Book2--");
        Book book2 = book1.clone();
        book2.addImage("小丑和精灵");
        book2.showBook();
        System.out.println("--Come Back--");
        book1.showBook();
    }
    
}

运行结果:

title:1001夜
image name:王子和公主
--About Book2--
title:1001夜
image name:王子和公主
image name:小丑和精灵
--Come Back--
title:1001夜
image name:王子和公主
image name:小丑和精灵

 

再看深复制,深复制把引用的变量指向复制过的新对象,而不是原有的被引用的对象。

还是刚才的例子,此时添加一行,表示对属性也调用clone进行复制

package com.designmodel.prototype;

import java.util.ArrayList;

public class Book implements Cloneable {

    private String title;
    private ArrayList<String> image = new ArrayList<String>();
    
    public Book() {
        
    }

    @Override
    protected Book clone() {
        try {
            Book book = (Book) super.clone();
            // 添加的语句
            book.image = (ArrayList<String>) this.image.clone();
            return book;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        
        return null;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public ArrayList<String> getImage() {
        return image;
    }

    public void setImage(ArrayList<String> image) {
        this.image = image;
    }
    
    public void addImage(String newImage) {
        this.image.add(newImage);
    }
    
    public void showBook() {
        System.out.println("title:" + title);
        for (String img : image) {
            System.out.println("image name:" + img);
        }

    }
    
}

客户端代码跟以前的一样,运行结果:

title:1001夜
image name:王子和公主
--About Book2--
title:1001夜
image name:王子和公主
image name:小丑和精灵
--Come Back--
title:1001夜
image name:王子和公主

 

可以看出,book1的内容并没有受到影响,这就是深复制

posted @ 2018-05-29 15:18  面条啊Andrew  阅读(128)  评论(0编辑  收藏  举报