大话设计模式学习笔记(9)——原型模式

源码git地址 https://github.com/dlovetco/designMode

问题提出

使用最简单的方法建立出多个相同的复杂对象(以水果为例,创建5个红色的重量为1kg的水果)。

看到这个问题,熟悉java的童鞋可能立马会想到一个东西——克隆。没错,java自身提供用于克隆(深拷贝)的api**Cloneable接口**。自己写的类如果要使用Object的clone()方法,则必须实现Cloneable接口,否则会抛出异常。下面我先用代码演示一下java中clone方法的基操。

clone

package prototype;

public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        Fruit apple1 = new Fruit("苹果", "红", 1);
        Fruit apple2 = apple1.clone();
        System.out.println(apple2);
    }
}

class Fruit implements Cloneable{
    private String name;

    private String color;

    private int kilogram;

    public Fruit(String name, String color, int kilogram) {
        this.name = name;
        this.color= color;
        this.kilogram = kilogram;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "name='" + name + '\'' +
                ", color='" + color+ '\'' +
                ", kilogram=" + kilogram +
                '}';
    }

    @Override
    protected Fruit clone() {
        try {
            return (Fruit) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}

用过clone方法的同学们能看到 我其实在原来方法上做了一点修改。主要是体现一条原则:永远不要让客户端去做任何类库能够替代客户完成的事情
注意:clone方法其实有很多的坑 具体我将会在effective java学习笔记中描述。
原型模式其实也就是这个样子,只不过需要我们自己写clone的内部实现。相比于object的clone方法灵活性更高。

原型模式

public class Prototype {
    public static void main(String[] args) throws CloneNotSupportedException {
        Fruit apple1 = new Fruit("苹果", "红", 1);
        Fruit apple2 = apple1.cloneFruit();
        System.out.println(apple2);
    }
}

class Fruit implements Cloneable {
    private String name;

    private String color;

    private int kilogram;

    public Fruit(String name, String color, int kilogram) {
        this.name = name;
        this.color = color;
        this.kilogram = kilogram;
    }

    @Override
    public String toString() {
        return "Fruit{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", kilogram=" + kilogram +
                '}';
    }

    //自己写的拷贝方法
    public Fruit cloneFruit() {
        return new Fruit(this.name, this.color, this.kilogram);
    }
}

此外要注意的一点是:上述例子中类里面只有基本类型的数据,并没有引用类型的数据。如果一个类里面有引用类型的数据,我们使用clone()方法就会出现意想不到的问题。因为clone方法对于引用类型的数据只是浅复制(即只会复制引用)。这样的话如果我们改变了原对象的引用类型数据,克隆对象的相应数据也会被改变。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值