设计模式之原型模式

原型模式

什么是原型模式?

用原型实例指定创建创建对象的种类,并且拷贝这些原型创建新的对象

原型模式解决了什么问题?

原型模式是根据已有的类创建一个相同状态的类,不需要再重新初始话一个类,动态获取了对象运行的状态。

如何使用原型模式?

Object类中默认定义了一个clone方法权限为Protected,我们需要重写这个方法并且增大权限为public。

java类库中定义了一个Cloneable接口,我们实现这个接口,尽管这个接口是空的。继承了这个接口,jvm才认为这个类是可以被克隆的。

由于原型模式比较简单,直接举例实现吧

浅克隆

创建一个具体的原型类,实现Cloneable接口,并且重写Object的clone方法,为了便于观察,我也重写了toString

public class ConcretePrototype implements Cloneable {
    private String name;
    private String age;

    public ConcretePrototype() {
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public ConcretePrototype(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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



    @Override
    protected ConcretePrototype clone() {
        try {
            ConcretePrototype clone = (ConcretePrototype )super.clone();
            return clone;
        } catch (CloneNotSupportedException e) {
            System.out.println("不支持克隆");
        }
        return null;
    }

    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
}

客户端类使用

public class Client {
    public static void main(String[] args) {
        ConcretePrototype c1 = new ConcretePrototype("小王");
        c1.setAge("20");
        ConcretePrototype c2 = c1.clone();
        c2.setAge("22");
        System.out.println(c1);
        System.out.println(c2);
    }
}
//输出
//ConcretePrototype{name='小王', age='20'}
//ConcretePrototype{name='小王', age='22'}

为什么说是浅克隆呢?

因为这种处理方法只能复制值,而对于引用型数据,则不会复制,此时克隆引用型数据,其所有相应变量相当于指针,指向同一个地址。

String类虽然是引用型,但也具有“值”的特性。

用一个例子复现

使用一个工作经验类当引用型数据

public class WorkExperience {
    private String experience;

    public WorkExperience() {
    }

    public WorkExperience(String experience) {
        this.experience = experience;
    }

    public String getExperience() {
        return experience;
    }

    public void setExperience(String experience) {
        this.experience = experience;
    }

    @Override
    public String toString() {
        return "WorkExperience{" +
                "experience='" + experience + '\'' +
                '}';
    }
}
public class Resume implements Cloneable{
    private WorkExperience work;
    private String name;

    public Resume(String name) {
        this.work = new WorkExperience();
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public void setWork(String years){
        work.setExperience(years);
    }

    @Override
    protected Resume clone() {
        try {
            return (Resume)super.clone();
        }catch (Exception e){
            System.out.println("不支持克隆");
        }
        return null;
    }

    @Override
    public String toString() {
        return "Resume{" +
                "work=" + work +
                ", name='" + name + '\'' +
                '}';
    }
}
public class Client {
    public static void main(String[] args) {

        Resume r1 = new Resume("小王");
        r1.setWork("三年开发");
        Resume r2 = r1.clone();
        r2.setWork("半年开发");
        System.out.println(r1);
        System.out.println(r2);

    }
}
//输出
//Resume{work=WorkExperience{experience='半年开发'}, name='小王'}
//Resume{work=WorkExperience{experience='半年开发'}, name='小王'}

深克隆

深克隆即可解决引用类数据可复制使用的问题

以上面的浅克隆为例,我们把浅克隆改成深克隆

public class WorkExperience implements Cloneable{
    private String experience;

    public WorkExperience() {
    }

    public WorkExperience(String experience) {
        this.experience = experience;
    }

    public String getExperience() {
        return experience;
    }

    public void setExperience(String experience) {
        this.experience = experience;
    }



    @Override
    public String toString() {
        return "WorkExperience{" +
                "experience='" + experience + '\'' +
                '}';
    }

    @Override
    protected WorkExperience clone()  {
        try{
            return (WorkExperience)super.clone();
        }catch (Exception e){
            System.out.println("不支持克隆");
        }
     return null;
    }
}
public class Resume implements Cloneable{
    private WorkExperience work;
    private String name;

    public Resume(String name) {
        this.work = new WorkExperience();
        this.name = name;
    }

    public WorkExperience getWork() {
        return work;
    }

    public void setWorks(WorkExperience work) {
        this.work = work;
    }

    public String getName() {
        return name;
    }

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

    public void setWork(String years){
        work.setExperience(years);
    }

    @Override
    protected Resume clone() {
        try {
            Resume resume = (Resume) super.clone();
            WorkExperience workExperience = work.clone();
            resume.setWorks(workExperience);
            return resume;

        }catch (Exception e){
            System.out.println("不支持克隆");
        }
        return null;
    }

    @Override
    public String toString() {
        return "Resume{" +
                "work=" + work +
                ", name='" + name + '\'' +
                '}';
    }
}

客户端类仍然相同,但结果为

Resume{work=WorkExperience{experience='三年开发'}, name='小王'}
Resume{work=WorkExperience{experience='半年开发'}, name='小王'}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值