Java-设计模式-第六篇-原型复制模式

本人所学设计模式皆出自于 结城浩先生的《图解设计模式》。

类图

    

为什么使用原型复制模式

    我们知道在很多的类中,我们需要这个了类去持有其他类的对象,又或者构成某一个类的对象十分复杂。又或者,你想解耦框架与生成的实例时,比如说下面我们是根据字符串指定要生成的实例,这样我们就可以把client封装到框架中,而不用因为new Something();必须导包,限制生成实例了。将框架从类名的约束中解放出来。

示例代码

package com.qiang.inte;

/**
 * 复制功能的接口
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public interface Product extends Cloneable {
    /**
     * 接口定义的某种功能
     *
     * @param string 参数
     */
    void use(String string);

    /**
     * 原型复制的方法,用于自我复制
     *
     * @return 你要复制的对象
     */
    Product createClone();
}
package com.qiang.inte.impl;

import com.qiang.inte.Product;

/**
 * 盒子产品
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class BoxProduct implements Product {
    @Override
    public void use(String string) {
        System.out.println("我用包装盒精美的包装着:" + string);
    }

    /**
     * 原型复制的方法,用于自我复制
     *
     * @return 盒子产品
     */
    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}
package com.qiang.inte.impl;

import com.qiang.inte.Product;

/**
 * 塑料袋产品
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class PlasticBagsProduct implements Product {
    @Override
    public void use(String string) {
        System.out.println("我用塑料袋装着:" + string);
    }

    /**
     * 原型复制的方法,用于自我复制
     *
     * @return 塑料袋产品
     */
    @Override
    public Product createClone() {
        Product product = null;
        try {
            product = (Product) clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return product;
    }
}
package com.qiang;

import com.qiang.inte.Product;

import java.util.HashMap;

/**
 * 注册中心
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class Register {
    private HashMap<String, Product> register = new HashMap<>();

    /**
     * 向注册中心注册原型
     *
     * @param name    原型的名字
     * @param product 原型
     */
    public void regist(String name, Product product) {
        register.put(name, product);
    }

    /**
     * 获取一个新的实例
     *
     * @param name 原型名字
     * @return 实例
     */
    public Product getInstance(String name) {
        Product product = register.get(name);
        return product.createClone();
    }
}
package com;

import com.qiang.Register;
import com.qiang.inte.Product;
import com.qiang.inte.impl.BoxProduct;
import com.qiang.inte.impl.PlasticBagsProduct;

/**
 * 测试类
 *
 * @author zhangxinqiang
 * @date 2018/5/28
 */
public class Test {
    public static void main(String[] args) {
        //进行注册
        Register register = new Register();
        BoxProduct boxProduct = new BoxProduct();
        PlasticBagsProduct plasticBagsProduct = new PlasticBagsProduct();
        register.regist("box", boxProduct);
        register.regist("plastic", plasticBagsProduct);

        //获取对象做事
        Product box1 = register.getInstance("box");
        box1.use("香蕉");
        Product box2 = register.getInstance("box");
        box2.use("香蕉");
        System.out.println(box1+"  !=  "+box2);

        Product plastic1 = register.getInstance("plastic");
        plastic1.use("香蕉");
        Product plastic2 = register.getInstance("plastic");
        plastic2.use("香蕉");

        System.out.println(plastic1+"  !=  "+plastic2);
    }
}

运行结果

我用包装盒精美的包装着:香蕉
我用包装盒精美的包装着:香蕉
com.qiang.inte.impl.BoxProduct@3cd1f1c8  !=  com.qiang.inte.impl.BoxProduct@3a4afd8d
我用塑料袋装着:香蕉
我用塑料袋装着:香蕉
com.qiang.inte.impl.PlasticBagsProduct@1996cd68  !=  com.qiang.inte.impl.PlasticBagsProduct@3339ad8e

思考一下

    每一个实际的产品都要去重复的书写createClone()方法,我们是不是可以通过模板模式来稍微修改一下呢,那样的话,我们再写具体的产品时,只要主义写产品的内部逻辑就可以了,而不用去关注clone了呢。

    CloneAble接口内部并没有任何方法,它只是起到标记作用,只有实现了这个接口的类,才可以调用Object类中的clone()方法。

(最近加班非常多,个人精力跟不上,更新会慢很多...)






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值