设计模式-原型模式(Prototype)

原型模式是一种对象创建型模式,它采用复制原型对象的方法来创建对象的实例。它创建的实例,具有与原型一样的数据结构和值

分为深度克隆浅度克隆

浅度克隆:克隆对象的值类型(基本数据类型),克隆引用类型的地址;

深度克隆:克隆对象的值类型,引用类型的对象也复制一份副本。

 

UML图:

具体代码:

浅度复制:

import java.util.List;

/**
 * 浅度复制
 */
public class ShallowPerson implements Cloneable{
    private String name;
    private List<String> friendNames;

    public List<String> getFriendNames() {
        return friendNames;
    }

    public void setFriendNames(List<String> friendNames) {
        this.friendNames = friendNames;
    }

    public String getName() {
        return name;
    }

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

    @Override
    protected ShallowPerson clone() throws CloneNotSupportedException {
        ShallowPerson person = (ShallowPerson)super.clone();
        return person;
    }
}
import java.util.ArrayList;
import java.util.List;

public class ShallowMain {
    public static void main(String[] args) throws CloneNotSupportedException {
        List<String> list = new ArrayList<String>();
        list.add("小明");
        list.add("小红");

        //浅度复制:只复制对象中的属性。对象中的对象,只复制地址
        ShallowPerson shallowPerson = new ShallowPerson();
        shallowPerson.setName("张三");
        shallowPerson.setFriendNames(list);
        ShallowPerson cloneShallowPerson = shallowPerson.clone();//浅度复制

        System.out.println(shallowPerson.getName());
        System.out.println(shallowPerson.getFriendNames());
        System.out.println(cloneShallowPerson.getName());
        System.out.println(cloneShallowPerson.getFriendNames());
        System.out.println("--------------------------------------------");

        list.add("小兰");
        System.out.println(shallowPerson.getName());
        System.out.println(shallowPerson.getFriendNames());
        System.out.println(cloneShallowPerson.getName());
        System.out.println(cloneShallowPerson.getFriendNames());
    }
}

结果:

张三
[小明, 小红]
张三
[小明, 小红]
--------------------------------------------
张三
[小明, 小红, 小兰]
张三
[小明, 小红, 小兰]

 

深度复制:

 

import java.util.ArrayList;
import java.util.List;

public class DepthPerson implements Cloneable{
    private String name;
    private List<String> friendNames;

    public List<String> getFriendNames() {
        return friendNames;
    }

    public void setFriendNames(List<String> friendNames) {
        this.friendNames = friendNames;
    }

    public String getName() {
        return name;
    }

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

    @Override
    protected DepthPerson clone() throws CloneNotSupportedException {
        List<String> list = new ArrayList<String>();
        DepthPerson person = (DepthPerson)super.clone();
        for(String frientName :this.getFriendNames()){
            list.add(frientName);
        }
        person.setFriendNames(list);
        return person;
    }
}

 

import java.util.ArrayList;
import java.util.List;

public class DepthMain {
    public static void main(String[] args) throws CloneNotSupportedException {
        List<String> list = new ArrayList<String>();
        list.add("小明");
        list.add("小红");

        //深度复制:对象中的属性和对象中的对象都复制
        DepthPerson depthPerson = new DepthPerson();
        depthPerson.setName("张三");
        depthPerson.setFriendNames(list);
        DepthPerson cloneDepthPerson = depthPerson.clone();//深度复制

        System.out.println(depthPerson.getName());
        System.out.println(depthPerson.getFriendNames());
        System.out.println(cloneDepthPerson.getName());
        System.out.println(cloneDepthPerson.getFriendNames());
        System.out.println("--------------------------------------------");

        list.add("小兰");
        System.out.println(depthPerson.getName());
        System.out.println(depthPerson.getFriendNames());
        System.out.println(cloneDepthPerson.getName());
        System.out.println(cloneDepthPerson.getFriendNames());
    }
}

结果:

张三
[小明, 小红]
张三
[小明, 小红]
--------------------------------------------
张三
[小明, 小红, 小兰]
张三
[小明, 小红]

 

应用场景:

1.创建对象的时候,我们不只希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。

2.希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互不影响)

 

 

 源码地址:https://github.com/qjm201000/design_pattern_prototype.git

 

posted @ 2018-12-03 14:03  qjm201000  阅读(168)  评论(0编辑  收藏  举报