23种设计模式中的原型模式

原型模式:通过复制现有实例来创建新的实例,无须知道相应类的信息。

个人见解:在大量循环时,需要初始化对象,用 原型模式能节省大量的初始化所花费的时间,值得一谈的是浅复制和深复制

浅复制:Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝

代码

在这里我定义了一个学生类Student.java

public class Student implements Cloneable {
    private String name;

    public Student(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return super.clone();
    }
}

还有一个Teacher.java

public class Teacher implements Cloneable {
    private String name;
    private Student[] students;

    public Teacher(String name, Student... students) {
        super();
        this.name = name;
        this.students = students;
    }

    public String getName() {
        return name;
    }

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

    public Student[] getStudents() {
        return students;
    }

    public void setStudents(Student[] students) {
        this.students = students;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return super.clone();
    }
}

然后测试

public static void main(String[] args) throws CloneNotSupportedException {
        Teacher t=new Teacher("李老师", new Student("小明"),new Student("小红"));
        System.out.println(t);
        System.out.println(t.getStudents());
        System.out.println(Arrays.toString(t.getStudents()));
        System.out.println("-------------------------------------------------");
        Teacher teacher = (Teacher) t.clone();
        System.out.println(teacher);
        System.out.println(teacher.getStudents());
        System.out.println(Arrays.toString(teacher.getStudents()));
    }

输出结果

可以看到拷贝出来的对象跟被拷贝的对象内存地址不一样,也就是不同的对象,但是指向的Student数组的内存地址是一样的,那就是说改变拷贝出来的对象中的Student数组会影响被拷贝的对象中的Student数组,这个在开发中很明显不是我们想要的,那么我们看一下深复制。

深复制:要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝

实例代码,

只需要改动Teacher.java

public class Teacher implements Cloneable {
    private String name;
    private Student[] students;

    public Teacher(String name, Student... students) {
        super();
        this.name = name;
        this.students = students;
    }

    public String getName() {
        return name;
    }

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

    public Student[] getStudents() {
        return students;
    }

    public void setStudents(Student[] students) {
        this.students = students;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        Teacher clone = null;
        clone = (Teacher) super.clone();
        clone.students = this.students.clone();
        return clone;
    }
}

输出结果

很明显,指向Student数组都不一样,那么就是连Student数组也拷贝了

大家有没有发现,为什么Student数组里面的字符串地址都是一样?这实际上是Java虚拟机对字符串的一种优化,并不在本章节的讨论范围内,大家有兴趣可以去了解下。

时间: 2024-07-30 06:38:49

23种设计模式中的原型模式的相关文章

23种设计模式[5]:原型模式

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. 类型:创建类模式 类图: 原型模式主要用于对象的复制,它的核心是就是类图中的原型类Prototype.Prototype类需要具备以下两个条件: 实现Cloneable接口.在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法.在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedExcepti

23种设计模式中的迭代器模式

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个对象. 那么如何提供一个方法顺序呢? public interface Iterator<T>{ public boolean hasNext(); public T next(); } public class XXX{ private List<XXX> list =new ArrayList<>(); public Iterator getIterator (){ return new XXXIterator()

23种设计模式中的桥接模式

桥接模式:将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变. 个人见解:实际上是为了同时实现两个协议,而让其中一个协议让父类实现而另一个协议自己实现. public interface IA{ public void a(); } public interface IB{ public void b(); } public ABfather implements IA{ @override public void a(){} } public AB extends ABfather i

23种设计模式中的访问者模式

访问者模式:对于一组对象,在不改变数据结构的前提下,增加作用于这些结构元素新的功能. 适用于数据结构相对稳定,它把数据结构和作用于其上的操作解耦,使得操作集合可以相对自由地演化. 优点: 符合单一职责原则 扩展性良好 有益于系统的管理和维护 缺点: 增加新的元素类变得很困难 破坏封装性 适用场合: 如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的

Java经典23种设计模式之结构型模式(二)

接上篇,本文介绍结构型模式里的组合模式.装饰模式.外观模式. 一.组合模式(Composite) 组合模式:将对象组合成树形结构,表示"部分--整体"的层次结构.最终达到单个对象和组合对象的使用具有一致性.单看这句话貌似有点抽象,其实比较简单. 以李云龙的独立团为例,目的要统计赵嘉宇一战共歼灭敌人多少个.最高的级别是团,一个团有若干个营,一个营有若干个排,一个排有若干个战士.(为了简化问题,排下面就不设行政单位了).很自然的,李云龙给营长开会回去给老子统计.营长回去给各个排长开会,赶紧

Java经典23种设计模式之行为型模式(三)

本文接着介绍11种行为型模式里的备忘录模式.观察者模式.状态模式. 一.备忘录模式 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可以将该对象恢复到原先保存的状态.还是比较好理解的. 1.Memento 备忘录存储原发器对象的内部状态,这个类就是要存储的对象的状态.状态需要多少个变量,在Memento里就写多少个变量. public class Memento { private String state; public Meme*to(String st

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

Java经典23种设计模式之结构型模式(一)

结构型模式包括7种:适配器模式.桥接模式.组合模式.装饰模式.外观模式.享元模式.代理模式. 本文主要介绍适配器模式和桥接模式. 一.适配器模式(Adapter) 适配器模式其实很简单,就像手机充电器一样,手机需要5V的,而插座出来是220V.因此需要充电器变压就ok.再比如,一个之会说汉语的和一个只会说英语的无法沟通,那就中间请个翻译.所有的交流通过翻译,翻译翻给会说英语的,就能完成一次单项交流的.链接1 中的例子非常生动形象了.总结一下,无非就是有个通用的接口(称为Target),如果一切顺

Java经典23种设计模式之行为型模式(一)

行为型设计模式有11种,分别是Chain of Responsibility ( 责任链模式 ).Command ( 命令模式 ).Interpreter ( 解释器模式 ) .Iterator ( 迭代器模式 ).Mediator ( 中介者模式 ) .Memento ( 备忘录模式 ) .Observer ( 观察者模式 ).State ( 状态模式 ) .Strategy ( 策略模式 ).TemplateMethod ( 模板方法 ).Visitor ( 访问者模式 ),本文介绍这11种