设计模式-原型模式

1.定义

通过复制现有的实例来创建新的实例,同时又能保证较高性能。

2.使用场景及设计

2.1.使用场景

创建对象耗时又耗费资源时候可以使用。

2.2.设计

使用原型模式克隆对象时候又分为浅拷贝深拷贝

  • 浅拷贝
    只拷贝目标对象,不拷贝对象的成员属性。
  • 深拷贝
    拷贝目标对象,并且拷贝对象的成员属性

3.测试代码

此处测试浅拷贝,入口代码

package com.glt.designpattern.prototype;

public class InitMain {

    public static void main(String[] args) {

        ShapeCache.loadShape();

        Shape circle = ShapeCache.getShape("1");
        circle.draw();
        System.out.println("circle hashcode=" + circle.hashCode());
        System.out.println("circle.type hashcode=" + circle.getType().hashCode());

        Shape circle2 = ShapeCache.getShape("1");
        circle2.draw();
        System.out.println("circle2 hashcode=" + circle2.hashCode());
        System.out.println("circle2.type hashcode=" + circle2.getType().hashCode());

        Shape square = ShapeCache.getShape("2");
        square.draw();
        System.out.println("square hashcode=" + square.hashCode());
        System.out.println("square.type hashcode=" + square.getType().hashCode());

        Shape square2 = ShapeCache.getShape("2");
        square2.draw();
        System.out.println("square2 hashcode=" + square2.hashCode());
        System.out.println("square2.type hashcode=" + square2.getType().hashCode());


    }
}

抽象类继承Cloneable接口

package com.glt.designpattern.prototype;


public abstract class Shape implements Cloneable {

    private String id;
    private String type;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }


    public abstract void draw();

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

圆形实现类继承抽象类

package com.glt.designpattern.prototype;

public class Circle extends Shape {

    public Circle(){
        this.setType("circle");
    }
    @Override
    public void draw() {
        System.out.println("this is 圆形");
    }
}

正方形实现类继承抽象类

package com.glt.designpattern.prototype;

public class Square extends Shape {

    public Square(){
        this.setType("square");
    }
    @Override
    public void draw() {
        System.out.println("this is 正方形");
    }
}

创建类生产原型对象

package com.glt.designpattern.prototype;

import java.util.Hashtable;

public class ShapeCache {

    private static Hashtable<String,Shape> map = new Hashtable<>();

    public static void loadShape(){
        Circle circle = new Circle();
        circle.setId("1");
        map.put(circle.getId(),circle);
        Square square = new Square();
        square.setId("2");
        map.put(square.getId(),square);
    }

    public static Shape getShape(String id){

        Shape shape = map.get(id);

        return (Shape) shape.clone();
    }
}

输出如下:

this is 圆形
circle hashcode=41359092
circle.type hashcode=-1360216880
this is 圆形
circle2 hashcode=149928006
circle2.type hashcode=-1360216880
this is 正方形
square hashcode=713338599
square.type hashcode=-894674659
this is 正方形
square2 hashcode=168423058
square2.type hashcode=-894674659

Process finished with exit code 0

如上所示,拷贝出来的目标对象的hashcode是不一样的,但是拷贝出来的同一原型的成员属性的hashcode的一样的,即使用的是同一引用。

4.总结

原型模式中的浅拷贝深拷贝的区别在于有没有拷贝其成员属性。
想要实现深拷贝只需要在实现的clone()方法中将目标对象的成员属性同时拷贝即可,也可以根据业务选择性拷贝成员属性。
原型模式优点:

  • 能够减少同类对象创建的资源消耗,提高性能。
  • 目标对象过于复杂的情况,使用原型模式比手工创建对象方便快捷。

缺点:

  • 有循环结构的类对象,使用原型模式会遇到很大困难。
  • 必须要继承java的Cloneable接口,实现clone()方法。

参考资料:

菜鸟教程
《Head Firsh 设计模式》(中文版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值