zoukankan      html  css  js  c++  java
  • [设计模式]原型模式

    1. 定义

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

    2. 类图

      

      Prototype:声明一个克隆自身的接口,用来约束想要克隆自己的类,要求它们都要实现这里定义的克隆方法。

      ConcretePrototype:实现Prototype接口的类,这些类真正实现了克隆本身的功能。

      Client:使用原型的客户端,首先要获取到原型实例对象,然后通过原型实例对象克隆本身来创建新的实例对象。

    3. 实例

      

    package com.jerry.designpattern;
    /**
     * 
     * @author Jerry
     * @date 2015年1月20日 上午9:41:10
     */
    public interface OrderApi {
        
        /**
         * 获得产品数量
         * @return
         */
        int getProductNumber();
        
        /**
         * 设置产品数量
         * @param num
         */
        void setProductNumber(int num);
        
        /**
         * 克隆订单
         * @return
         */
        OrderApi cloneOrder();
        
    }
    
    package com.jerry.designpattern;
    /**
     * 
     * @author Jerry
     * @date 2015年1月20日 上午10:01:09
     */
    public class OrderBusiness {
        /**
         * 保存订单
         * 如果存在订单的产品数量大于1000,则生成新的订单,直至小于数量1000
         * @param order
         */
        public void saveOrder(OrderApi order) {
            while (order.getProductNumber() > 1000) {
                System.out.println("订单数量为" + order.getProductNumber() + ",超过1000,需要拆分订单。");
                OrderApi newOrder = order.cloneOrder();
                newOrder.setProductNumber(1000);
                order.setProductNumber(order.getProductNumber() - 1000);
                System.out.println("拆分出新的订单:" + newOrder);
            }
            System.out.println("订单:" + order);
        }
    }
    
    package com.jerry.designpattern;
    /**
     * 
     * @author Jerry
     * @date 2015年1月20日 上午9:53:50
     */
    public class PersonalOrder implements OrderApi{
        
        private String customerName;
        private int productId;
        private int productNumber;
        
        
        
        public String getCustomerName() {
            return customerName;
        }
    
        public void setCustomerName(String customerName) {
            this.customerName = customerName;
        }
    
        public int getProductId() {
            return productId;
        }
    
        public void setProductId(int productId) {
            this.productId = productId;
        }
    
        @Override
        public int getProductNumber() {
            // TODO Auto-generated method stub
            return this.productNumber;
        }
    
        @Override
        public void setProductNumber(int productNumber) {
            // TODO Auto-generated method stub
            this.productNumber = productNumber;
        }
    
        @Override
        public OrderApi cloneOrder() {
            // TODO Auto-generated method stub
            PersonalOrder order = new PersonalOrder();
            order.setCustomerName(this.customerName);
            order.setProductId(this.productId);
            order.setProductNumber(this.productNumber);
            return order;
        }
        
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "个人订单人为:" + this.customerName + ",订购产品为:" 
                    + this.productId + ",订购产品数量为:" + this.productNumber;
        }
        
    }
    
    package com.jerry.designpattern;
    /**
     * 
     * @author Jerry
     * @date 2015年1月20日 上午9:57:16
     */
    public class EnterpriseOrder implements OrderApi{
    
        private String enterpriseName;
        private int productId;
        private int productNumber;
        
        public String getEnterpriseName() {
            return enterpriseName;
        }
    
        public void setEnterpriseName(String enterpriseName) {
            this.enterpriseName = enterpriseName;
        }
    
        public int getProductId() {
            return productId;
        }
    
        public void setProductId(int productId) {
            this.productId = productId;
        }
    
        @Override
        public int getProductNumber() {
            // TODO Auto-generated method stub
            return this.productNumber;
        }
    
        @Override
        public void setProductNumber(int productNumber) {
            // TODO Auto-generated method stub
            this.productNumber = productNumber;
        }
    
        @Override
        public OrderApi cloneOrder() {
            // TODO Auto-generated method stub
            EnterpriseOrder order = new EnterpriseOrder();
            order.setEnterpriseName(this.enterpriseName);
            order.setProductId(this.productId);
            order.setProductNumber(this.productNumber);
            return order;
        }
    
    }
    
    package com.jerry.designpattern;
    /**
     * 
     * @author Jerry
     * @date 2015年1月20日 上午10:07:24
     */
    public class Client {
        public static void main(String[] args) {
            PersonalOrder order = new PersonalOrder();
            order.setCustomerName("Jerry");
            order.setProductId(123456);
            order.setProductNumber(42223);
            
            OrderBusiness orderBusiness = new OrderBusiness();
            orderBusiness.saveOrder(order);
        }
    }

    4. 原型模式的功能

      原型模式的功能实际上包含两个方面,第一个是通过克隆来创建新的对象实例,第二个是为克隆出来的对象实例复制原型对象实例属性值。

      原型模式从某种意义上来说,就像是new操作,只是类似于new操作,new一个对象实例,一般属性是没有值或者是默认值,而克隆得到的对象实例,通常都是有值的,一般都是原型对象实例克隆时的值。

    5. 深度克隆和浅度克隆

      原型模式是通过克隆创建新的对象实例,因此涉及到深度克隆和浅度克隆的问题,那什么是深度克隆和浅度克隆呢?

      浅度克隆:只负责克隆按值传递的数据,比如基本数据类型、String类型。

      深度克隆:除了浅度克隆要克隆的值外,还负责克隆引用类型的数据,基本上就是被克隆实例所有的属性数据都会被克隆出来。

      实现深度克隆也不是很复杂,只需要实现所有的引用类型的克隆功能,创建时调用它的克隆方法就可以了。

    6. 原型的优缺点

      原型的优点有:

        a) 对客户端隐藏具体的实现类型

        b) 在运行时动态改变具体的实现类型

      原型最大的缺点是所有类都要实现克隆方法,特别存在引用类型,比较麻烦。

  • 相关阅读:
    xiaopiu产品原型设计与团队实时协作平台
    asp.net webform过滤器(注意我们可以在拦截请求的同时设置回调函数)
    wdScrollTab
    pageoffice实现网页打开编辑保存word文档(基于SSM框架)
    ESB企业服务总线
    JRebel for IntelliJ
    dtcms 手机浏览
    maven仓库添加jar架包
    shell脚本实现FTP自动上传文件
    mysql创建数据库指定字符集
  • 原文地址:https://www.cnblogs.com/jerry19890622/p/4296165.html
Copyright © 2011-2022 走看看