原型模式

一:浅拷贝

被引用的类

package com.wing.mall.base.prototype;

import lombok.Data;

/**
 * @ProjectName: baby
 * @Package: com.wing.mall.base.prototype
 * @ClassName: Subject
 * @Author: heluwei
 * @Description: 对象拷贝的类
 * @Date: 2020/4/14 10:14
 * @Version: 1.0
 */
@Data
public class Subject {
    private String name;

    public Subject(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "[Subject: " + this.hashCode() + ",name:" + name + "]";
    }
}

要拷贝的对象

package com.wing.mall.base.prototype;

import lombok.Data;

import java.io.*;

/**
 * @ProjectName: baby
 * @Package: com.wing.mall.base.prototype
 * @ClassName: User
 * @Author: heluwei
 * @Description: 原型模式
 * @Date: 2020/4/14 8:56
 * @Version: 1.0
 */
@Data
public class User implements Serializable, Cloneable {
    private static final long serialVersionUID = 1L;
    //引用类型
    private Subject subject;
    //基本类型
    private Long id;
    private String name;

    public User() {
    }

    public User(Long id, String name) {
        this.id = id;
        this.name = name;
    }

    //浅拷贝
    protected Object shallowClone(){
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    @Override
    public String toString() {
        return "User{" +
                "subject=" + subject +
                ", id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

测试:


package com.wing.mall.base.prototype;

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

/**
* @ProjectName: baby
* @Package: com.wing.mall.base.prototype
* @ClassName: TestPrototype
* @Author: heluwei
* @Description: 利用原型模式
* @Date: 2020/4/14 8:57
* @Version: 1.0
*/
public class TestPrototype {
public static void main(String[] args) {
//浅拷贝
Subject subject = new Subject("yuwen");
User userA = new User();
userA.setSubject(subject);
userA.setId(1L);
userA.setName("张三");
User userB = (User) userA.shallowClone();
userB.setId(2L);
userB.setName("李四");
Subject subjectB = userB.getSubject();
subjectB.setName("lishi");
System.out.println("userA:" + userA.toString()+":"+userA.hashCode());
System.out.println("userB:" + userB.toString()+":"+userB.hashCode());
}

}
 

 

输出结果:

userA:User{subject=[Subject: 102982226,name:lishi], id=1, name='张三'}:1999823465
userB:User{subject=[Subject: 102982226,name:lishi], id=2, name='李四'}:1999890696

可以看到输出的hashCode(). User类继承了Cloneable。输出的hashCode不一致。当修改userA的时候。userB不会被影响。但是Subject会被影响。

二:深拷贝

Subject实现Cloneable接口
package com.wing.mall.base.prototype;

import lombok.Data;

/**
 * @ProjectName: baby
 * @Package: com.wing.mall.base.prototype
 * @ClassName: Subject
 * @Author: heluwei
 * @Description: 对象拷贝的类
 * @Date: 2020/4/14 10:14
 * @Version: 1.0
 */
@Data
public class Subject implements Cloneable {
    private String name;

    public Subject(String name) {
        this.name = name;
    }

    //重写Object的clone()方法。
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "[Subject: " + this.hashCode() + ",name:" + name + "]";
    }
}

在User类中重写clone方法。

//深拷贝
    protected Object deepClone(){
        try {
            // 直接调用父类的clone()方法
            User user = (User) super.clone();
            user.subject = (Subject)subject.clone();
            return user;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

输出:

userA:User{subject=[Subject: 115349247,name:yuwen], id=1, name='张三'}:2099750606
userB:User{subject=[Subject: 102982226,name:lishi], id=2, name='李四'}:1999890696

应用:在for循环中创建对象

public static void main(String[] args) {
        User user = new User();
        List<User> userList = new ArrayList<>();
        for (long i = 0; i < 5; i++) {
            User prototypeUser = (User)user.clone();
            prototypeUser.setId(i);
            prototypeUser.setName(String.valueOf(i));
            userList.add(prototypeUser);
        }
        userList.forEach(user1 -> {
            System.out.println(user1+"hashCode:"+user1.hashCode());
        });
    }

输出结果:

User{, id=0, name='0'}hashCode:3529
User{, id=1, name='1'}hashCode:3589
User{, id=2, name='2'}hashCode:3649
User{, id=3, name='3'}hashCode:3709
User{, id=4, name='4'}hashCode:3769

 

posted @ 2020-04-14 10:58  陆伟  阅读(176)  评论(0编辑  收藏  举报