java设计模式(创建型)之原型模式

第0章:简介

原型模式定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

原型模式的实质:克隆生成对象

参考:http://chjavach.iteye.com/blog/1623968,研磨设计模式(书籍),大话设计模式(书籍)

模式图:

待补充

第1章:实践

第0节:自定义原型模式

(1)原型接口(Prototype.java)

package com.mcc.core.designPattern.build.prototype.customPrototype;

/**
 * 原型接口
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午4:59
 */
public interface Prototype {
    /**
     * 克隆自身的方法
      * @return
     */
    public Prototype clone();
}

(2)产品类(Product.java)

package com.mcc.core.designPattern.build.prototype.customPrototype;

/**
 * 产品类(自定义)
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午5:04
 */
public class Product implements Prototype {

    private String property1;

    private String property2;

    public String getProperty1() {
        return property1;
    }

    public void setProperty1(String property1) {
        this.property1 = property1;
    }

    public String getProperty2() {
        return property2;
    }

    public void setProperty2(String property2) {
        this.property2 = property2;
    }

    @Override
    public String toString() {
        return "Product{" +
                "property1='" + property1 + '\'' +
                ", property2='" + property2 + '\'' +
                '}';
    }

    /**
     * 克隆自身,属性是值类型,属于浅度克隆
     * @return
     */
    @Override
    public Prototype clone() {
        Product product = new Product();
        product.setProperty1(this.property1);
        product.setProperty2(this.property2);
        return product;
    }
}

(3)目标克隆对象类(PrototypeImpl.java)

package com.mcc.core.designPattern.build.prototype.customPrototype;

/**
 * 目标克隆对象(自定义)
 *
 * 原型模式的定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
 * 原型模式的本质:克隆生成对象
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午5:06
 */
public class PrototypeImpl implements Prototype {

    //值类型属性
    private String property3;
    private String property4;

    //引用类型属性
    private Product product;

    public String getProperty3() {
        return property3;
    }

    public void setProperty3(String property3) {
        this.property3 = property3;
    }

    public String getProperty4() {
        return property4;
    }

    public void setProperty4(String property4) {
        this.property4 = property4;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    @Override
    public String toString() {
        return "PrototypeImpl{" +
                "property1='" + product.getProperty1() + '\'' +
                "property2='" + product.getProperty2() + '\'' +
                "property3='" + property3 + '\'' +
                ", property4='" + property4 + '\'' +
                '}';
    }

    /**
     * 对象克隆自身,含引用类型属性,采用深度克隆方式
     * @return
     */
    @Override
    public Prototype clone() {
        PrototypeImpl prototypeImpl = new PrototypeImpl();
        prototypeImpl.setProperty3(this.property3);
        prototypeImpl.setProperty4(this.property4);
        //引用类型属性克隆
        prototypeImpl.setProduct((Product)this.product.clone());
        return prototypeImpl;
    }
}

(4)客户端测试类(Client.java)

package com.mcc.core.designPattern.build.prototype.customPrototype;

/**
 * 客户端测试
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午5:20
 */
public class Client {

    public static void main(String args[]){

        //第一个实例
        PrototypeImpl prototypeImpl1 =  new PrototypeImpl();
        Product product = new Product();
        product.setProperty1("value1");
        product.setProperty2("value2");
        prototypeImpl1.setProduct(product);
        prototypeImpl1.setProperty3("value3");
        prototypeImpl1.setProperty4("value4");
        System.out.println("第一个实例:" + prototypeImpl1);

        //第二个实例,通过克隆获取

        PrototypeImpl prototypeImpl2 = (PrototypeImpl)prototypeImpl1.clone();
        //修改值
        prototypeImpl2.getProduct().setProperty1("值1");
        prototypeImpl2.setProperty3("值3");
        System.out.println("第二个实例(克隆):" + prototypeImpl2);

        System.out.println("再看第一个实例(原实例):" + prototypeImpl1);

    }
}

第1节:java自带原型模式

(1)产品类(Product.java)

package com.mcc.core.designPattern.build.prototype.javaPrototype;

/**
 * 产品对象(Java自实现)
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午5:04
 */
public class Product implements Cloneable {

    private String property1;

    private String property2;

    public String getProperty1() {
        return property1;
    }

    public void setProperty1(String property1) {
        this.property1 = property1;
    }

    public String getProperty2() {
        return property2;
    }

    public void setProperty2(String property2) {
        this.property2 = property2;
    }

    @Override
    public String toString() {
        return "Product{" +
                "property1='" + property1 + '\'' +
                ", property2='" + property2 + '\'' +
                '}';
    }

    /**
     * 克隆自身,属性是值类型,属于浅度克隆
     * @return
     */
    public Object clone() {
        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        return obj;
    }
}

(2)目标克隆对象类(PrototypeImpl.java)

package com.mcc.core.designPattern.build.prototype.javaPrototype;

/**
 * 目标克隆对象(Java自实现)
 *
 * 原型模式的定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
 * 原型模式的本质:克隆生成对象
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午5:06
 */
public class PrototypeImpl implements Cloneable {

    //值类型属性
    private String property3;
    private String property4;

    //引用类型属性
    private Product product;

    public String getProperty3() {
        return property3;
    }

    public void setProperty3(String property3) {
        this.property3 = property3;
    }

    public String getProperty4() {
        return property4;
    }

    public void setProperty4(String property4) {
        this.property4 = property4;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    @Override
    public String toString() {
        return "PrototypeImpl{" +
                "property1='" + product.getProperty1() + '\'' +
                "property2='" + product.getProperty2() + '\'' +
                "property3='" + property3 + '\'' +
                ", property4='" + property4 + '\'' +
                '}';
    }

    /**
     * 对象克隆自身,含引用类型属性,采用深度克隆方式
     * @return
     */
    public Object clone() {
        PrototypeImpl obj = null;
        try {
            obj = (PrototypeImpl)super.clone();
            //这个很重要,引用类型自身克隆
            obj.setProduct((Product)this.product.clone());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

(3)客户端测试(Client.java)

package com.mcc.core.designPattern.build.prototype.javaPrototype;


/**
 * 客户端测试
 *
 * @author <a href="mailto:417877417@qq.com">menergy</a>
 *         DateTime: 14-3-9  下午5:51
 */
public class Client {

    public static void main(String args[]){

        //第一个实例
        PrototypeImpl prototypeImpl1 =  new PrototypeImpl();
        Product product = new Product();
        product.setProperty1("value1");
        product.setProperty2("value2");
        prototypeImpl1.setProduct(product);
        prototypeImpl1.setProperty3("value3");
        prototypeImpl1.setProperty4("value4");
        System.out.println("第一个实例:" + prototypeImpl1);

        //第二个实例,通过克隆获取

        PrototypeImpl prototypeImpl2 = (PrototypeImpl)prototypeImpl1.clone();
        //修改值
        prototypeImpl2.getProduct().setProperty1("值1");
        prototypeImpl2.setProperty3("值3");
        System.out.println("第二个实例(克隆):" + prototypeImpl2);

        System.out.println("再看第一个实例(原实例):" + prototypeImpl1);
    }
}

思考:

Java自带的原型模式,要求实现Cloneable接口,实现机制是在运行时通知虚拟机可以安全的使用Clone方法,如果没有实现这个接口却去调用,则会抛出CloneNotSupportedException异常。java中所有的类都是Object类的子类,Object类中有一个clone方法,该方法的作用域时protected类型,一般的类时无法调用的。Prototype类会将clone方法的作用域修改为public类型。而且,对象的复制是通过调用Object类的clone方法,不会调用类的构造方法,它直接在内存中复制数据。因此,不但构造方法中的代码不会执行,甚至连访问权限都对原型模式无效。

原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。原型模式很少单独出现。经常与其他模式混用。

需要注意, 单例模式将构造方法的访问权限设置为private型。但clone方法直接无视构造方法的权限,所以,单例模式与原型模式是冲突的,在使用时要特别注意。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值