【设计模式(三)】原型模式

一、原型模式概述

原型模式是指:用原型实例指定创建对象的种类,并通过拷贝这些原型,创建新的对象。原型模式是一种创建型设计模式,允许一个对象再创建一个可定制的对象,无须知道知道如何创建的对象。用大白话解释就是,已知一个对象,再根据这个对象复制一个一模一样的对象

二、关于深拷贝和浅拷贝

深拷贝:就是对象里面无论有属性或者方法,在复制新对象的时候,都全部拷贝过来,形成一个新的对象。

浅拷贝:就是只能复制对象里面的基本属性,如果对象里面有些属性是另一个对象,则不是复制一个新的,而是将拷贝的对象里面的这个对象和被复制的这个对象里面的对象属性是同一个对象。这么说估计估计有点晕,一图解千言,看图:

浅拷贝就是对象里面的对象不能复制,这里在克隆的时候,只是将A对象中的school对象的引用传递给了B对象的school。那么就意味,无论你是改变A对象里面的school还是改变B对象里面的school,都将相互影响。那么深拷贝就不言而喻了三,就是school也完全复制了一个新的,A对象和B对象里面的school互相没有关系了。

三、实现浅拷贝

就是刚才的Sudent类,要实现克隆,必须要实现Cloneable接口,如下:

public class Student implements Cloneable{
    private String username;
    private String password;
    private School school;

    public Student(String username, String password, School school) {
        this.username = username;
        this.password = password;
        this.school = school;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    /**
     * 实现克隆方法
     * @return
     */
    @Override
    protected Object clone() {
        Student student = null;
        try {
            student = (Student) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return student;
    }
}
public class School {
    private String name;
    private String address;

    public School(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

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

开始克隆:

四、clone方法实现深拷贝

clone方法实现深拷贝,也简单再将school对象也克隆一次,当然Student也要实现Cloneable接口

public class School implements Cloneable {
    private String name;
    private String address;

    public School(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

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

    @Override
    protected Object clone() {
        School school = null;
        try {
            school = (School) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return school;
    }
}


public class Student implements Cloneable{
    private String username;
    private String password;
    private School school;

    public Student(String username, String password, School school) {
        this.username = username;
        this.password = password;
        this.school = school;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    /**
     * 实现克隆方法
     * @return
     */
    @Override
    protected Object clone() {
        Student student = null;
        try {
            student = (Student) super.clone();
            student.school = (School) school.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return student;
    }
}

请注意Student的clone方法不一样了,在student的clone方法中,又实现了调用了一次school的clone方法。

开始克隆:

相信大家都发现了一个问题了,那就是如果对象中有对象,对象中还有对象,那么就会无休止的去写clone方法。所以下面用对象序列化实现深拷贝。

五、对象序列化实现深拷贝

依然是创建Student类和School类,但是要想实现序列化和反序列化,两个类都必须实现Serializable接口

import java.io.Serializable;

public class School implements Serializable {
    private String name;
    private String address;

    public School(String name, String address) {
        this.name = name;
        this.address = address;
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}
import java.io.*;

public class Student implements Serializable {
    private String username;
    private String password;
    private School school;

    public Student deepClone() {
        //输出流
        ByteArrayOutputStream byteArrayOutputStream = null;
        ObjectOutputStream objectOutputStream = null;
        //输入流
        ByteArrayInputStream byteArrayInputStream = null;
        ObjectInputStream objectInputStream = null;

        try {
            //输出流将对象输出到内存中(序列化)
            byteArrayOutputStream = new ByteArrayOutputStream();
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(this);

            //将内存中的对象读进来(反序列化)
            byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return (Student)objectInputStream.readObject();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public Student(String username, String password, School school) {
        this.username = username;
        this.password = password;
        this.school = school;
    }

    @Override
    public String toString() {
        return "Student{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", school=" + school +
                '}';
    }
}

客户端代码如下:

public class Client {
    public static void main(String[] args) {
        Student student = new Student("波仔","123",new School("杠山大学","中岗"));
        Student newStudent = student.deepClone();
        System.out.println(newStudent);
        System.out.println(student == newStudent);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 第1章UML类图实训 1.1知识讲解 1.1.1UML概述 1.1.2类与类的UML表示 1.1.3类之间的关系 1.2实训实例 1.2.1类图实例之图书管理系统 1.2.2类图实例之商场会员管理系统 1.3实训练习 第2章面向对象设计原则实训 2.1知识讲解 2.1.1面向对象设计原则概述 2.1.2单一职责原则 2.1.3开闭原则 2.1.4里氏代换原则 2.1.5依赖倒转原则 2.1.6接口隔离原则 2.1.7合成复用原则 2.1.8迪米特法则 2.2实训实例 2.2.1单一职责原则实例分析 2.2.2开闭原则实例分析 2.2.3里氏代换原则实例分析 2.2.4依赖倒转原则实例分析 2.2.5接口隔离原则实例分析 2.2.6合成复用原则实例分析 2.2.7迪米特法则实例分析 2.3实训练习 第3章创建型模式实训 3.1知识讲解 3.1.1设计模式 3.1.2创建型模式概述 3.1.3简单工厂模式 3.1.4工厂方法模式 3.1.5抽象工厂模式 3.1.6建造者模式 3.1.7原型模式 3.1.8单例模式 3.2实训实例 3.2.1简单工厂模式实例之图形工厂 3.2.2工厂方法模式实例之日志记录器 3.2.3抽象工厂模式实例之数据库操作工厂 3.2.4建造者模式实例之游戏人物角色 3.2.5原型模式实例之快速创建工作周报 3.2.6单例模式实例之多文档窗口 3.3实训练习 第4章结构型模式实训 4.1知识讲解 4.1.1结构型模式概述 4.1.2适配器模式 4.1.3桥接模式 4.1.4组合模式 4.1.5装饰模式 4.1.6外观模式 4.1.7享元模式 4.1.8代理模式 4.2实训实例 4.2.1适配器模式实例之算法适配 4.2.2桥接模式实例之跨平台视频播放器 4.2.3组合模式实例之杀毒软件 4.2.4装饰模式实例之界面显示构件库 4.2.5外观模式实例之文件加密 4.2.6享元模式实例之围棋棋子 4.2.7代理模式实例之日志记录代理 4.3实训练习 第5章行为型模式实训 5.1知识讲解 5.1.1行为型模式概述 5.1.2职责链模式 5.1.3命令模式 5.1.4解释器模式 5.1.5迭代器模式 5.1.6中介者模式 5.1.7备忘录模式 5.1.8观察者模式 5.1.9状态模式 5.1.10策略模式 5.1.11模板方法模式 5.1.12访问者模式 5.2实训实例 5.2.1职责链模式实例之在线文档帮助系统 5.2.2命令模式实例之公告板系统 5.2.3解释器模式实例之机器人控制程序 5.2.4迭代器模式实例之商品名称遍历 5.2.5中介者模式实例之温度转换器 5.2.6备忘录模式实例之游戏恢复点设置 5.2.7观察者模式实例之股票变化 5.2.8状态模式实例之银行账户 5.2.9策略模式实例之电影票打折 5.2.10模板方法模式实例之数据库操作 5.2.11访问者模式实例之奖励审批 5.3实训练习 第6章模式联用与综合实例实训 6.1设计模式补充知识 6.1.1反射与配置文件 6.1.2GRASP模式 6.1.3架构模式与MVC 6.2模式联用实训 6.2.1适配器模式与桥接模式联用 6.2.2组合模式与命令模式联用 6.2.3外观模式与单例模式联用 6.2.4原型模式与备忘录模式联用 6.2.5观察者模式与组合模式联用 6.2.6访问者模式、组合模式与迭代器模式联用 6.3综合实例实训 6.3.1多人联机射击游戏 6.3.2数据库同步系统 6.4实训练习 附录A参考答案 A.1第1章实训练习参考答案 A.2第2章实训练习参考答案 A.3第3章实训练习参考答案 A.4第4章实训练习参考答案 A.5第5章实训练习参考答案 A.6第6章实训练习参考答案 参考文献

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值