创建型设计模式-prototype

创建型设计模式-prototype

原型设计模式已经继承到java中,即通过clone方法复制一个对象。类图如下:

ProtoType模式需要满足以下两个条件

1 .实现Cloneable接口,只有实现Cloneable接口,在运行期才可以安全的复制对象,否则会报CloneNotSupportedException异常

2.重写Object类中的clone方法。Object为所有类的父类,因为Object中的Clone访问使用Protected修饰,故需要子类重写Clone方法,使用public修饰。

使用clone方法复制对象和使用构造new对象有什么区别吗?为什么设计模式建议使用clone,而不是重新new 对象呢?
  1. 当调用对象的clone方法时,首先会分配一个和原对象大小相同的空间,使用原对象中对应的各个域,填充新对象的域,然后返回。它直接操作内存中的二进制流,在复制大对象时,性能差别很明显。
    2.如果创建类通过new的过程很复杂,使用prototype可以省去大量创建代码。

深拷贝 and 浅拷贝 
  浅拷贝只会拷贝结基本的数据类型,对于数组、容器对象引用对象等都不会拷贝,如果需求中可能有会设置改变
原类型中数组或容器或引用对象操作则会出现以下问题。

**
 * Created by fengxinzi on 18-1-17.
 */
public class Glass implements Cloneable {

    String color ;

    String heigh ;
    
    public Water getWater() {
        return water;
    }
    public void setWater(Water water) {
        this.water = water;
    }

    private Water water ;

    public Glass(String color , String heigh , Water water){
        this.color = color;
        this.heigh = heigh;
        this.water = water;
    }
    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String getHeigh() {
        return heigh;
    }

    public void setHeigh(String heigh) {
        this.heigh = heigh;
    }

    public Glass Clone() throws CloneNotSupportedException{
        return (Glass)super.clone();
    }
}
/**
 * Created by fengxinzi on 18-1-17.
 */
public class Water {
    String colorName ;

    public Water(String colorName){
        this.colorName = colorName;
    }

    public void setColorName (String colorName){
        this.colorName = colorName;
    }

    public String getColorName(){
        return colorName;
    }
}
public class CloneTest {
    @Test
    public void testClone(){

        Water water = new Water("可乐");
        Glass glass = new Glass("透明","10cm",water);
        Glass cloneGlass = null;
        try {
            cloneGlass = glass.Clone();
        }catch(CloneNotSupportedException e){
            e.printStackTrace();
        }
        if(cloneGlass != null){
            //克隆的基本数据类型完全隔离,不会影响原型。
            cloneGlass.setColor("不透明");
            System.out.println(cloneGlass.getColor());
            System.out.println(glass.getColor());
            //克隆的引用类型默认不隔离,影响原型
           // Water water1 = new Water("咖啡");
            cloneGlass.getWater().setColorName("咖啡");
            System.out.println(cloneGlass.getWater().getColorName());
            System.out.println(glass.getWater().getColorName());
        }
    }
}

输出如下

不透明
透明
咖啡
咖啡

此时需要进行深拷贝,所谓深拷贝就是把对象中可能会被改变的数据、容器、引用对象另行拷贝。因为大部分容器类都已经实现了Cloneabel接口,所以可以在protoType抽象类中直接调用容器类的clone方法。

cloneGlass = glass.Clone();
cloneGlass.water =cloneGlass.water.Clone();

4 原型模式直接通过二进制流赋值对象,所以不care 访问修饰符。而单例模式中通过修改构造的修饰符来达到单例。故两个设计模式是冲突的,使用时候应该注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值