17. 原型模式

17 原型模式

  1. 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
  2. 本质:克隆生成对象
  3. 优点
    1. 对客户端隐藏具体的实现类型
    2. 在运行时动态改变具体的实现类型
  4. 缺点
    1. 深度克隆方法实现会比较困难,必须要能够递归的让所有的相关对象都要正确的实现克隆
  5. 使用场景
    1. 如果一个系统想要独立于它想要使用的对象时,可以使用原型模式,让系统只面向接口编程,在系统需要新的对象的时候,可以通过克隆原型来得到
    2. 如果需要实例化的类是在运行时刻动态指定时,可以使用原型模式,通过克隆原型来得到需要的实例
  6. 类图
    在这里插入图片描述
17.1 代码
  1. OrderApi

    /**
     * 订单的接口,声明了可以克隆自身的方法
     */
    public interface OrderApi {
        public int getOrderProductNum();
        public void setOrderProductNum(int num);
        /**
         * 克隆方法
         * @return 订单原型的实例
         */
        public OrderApi cloneOrder();
    }
    
  2. PersonalOrder

    /**
     * 个人订单对象
     */
    public class PersonalOrder implements OrderApi{
        private String customerName;
        private String productId;
        private int orderProductNum = 0;
    
        public int getOrderProductNum() {
            return this.orderProductNum;
        }
        public void setOrderProductNum(int num) {
            this.orderProductNum = num;
        }
        public String getCustomerName() {
            return customerName;
        }
        public void setCustomerName(String customerName) {
            this.customerName = customerName;
        }
        public String getProductId() {
            return productId;
        }
        public void setProductId(String productId) {
            this.productId = productId;
        }
        public String toString(){
            return "本个人订单的订购人是="+this.customerName+",订购产品是="+this.productId+",订购数量为="+this.orderProductNum;
        }
        public OrderApi cloneOrder() {
            //创建一个新的订单,然后把本实例的数据复制过去
            PersonalOrder order = new PersonalOrder();
            order.setCustomerName(this.customerName);
            order.setProductId(this.productId);
            order.setOrderProductNum(this.orderProductNum);
    
            return order;
        }
    }
    
  3. EnterpriseOrder

    /**
     * 企业订单对象
     */
    public class EnterpriseOrder implements OrderApi{
        private String enterpriseName;
        private String productId;
        private int orderProductNum = 0;
        public int getOrderProductNum() {
            return this.orderProductNum;
        }
        public void setOrderProductNum(int num) {
            this.orderProductNum = num;
        }
        public String getEnterpriseName() {
            return enterpriseName;
        }
        public void setEnterpriseName(String enterpriseName) {
            this.enterpriseName = enterpriseName;
        }
        public String getProductId() {
            return productId;
        }
        public void setProductId(String productId) {
            this.productId = productId;
        }
        public String toString(){
            return "本企业订单的订购企业是="+this.enterpriseName+",订购产品是="+this.productId+",订购数量为="+this.orderProductNum;
        }
        public OrderApi cloneOrder() {
            //创建一个新的订单,然后把本实例的数据复制过去
            EnterpriseOrder order = new EnterpriseOrder();
            order.setEnterpriseName(this.enterpriseName);
            order.setProductId(this.productId);
            order.setOrderProductNum(this.orderProductNum);
            return order;
        }
    }
    
  4. OrderBusiness

    /**
     * 处理订单的业务对象
     */
    public class OrderBusiness {
        /**
         * 创建订单的方法
         * @param order 订单的接口对象
         */
        public void saveOrder(OrderApi order){
            //1:判断当前的预定产品数量是否大于1000
            while(order.getOrderProductNum() > 1000){
                //如果OrderApi接口中没有cloneOrder方法, 那么你在这个位置由于并不知道cloneOrder的真实类型,所以无法创建一个cloneOrder对象出来
                //2:如果大于,还需要继续拆分
                //2.1再新建一份订单,跟传入的订单除了数量不一样外,其它都相同
                OrderApi newOrder = order.cloneOrder();
                //然后进行赋值,产品数量为1000
                newOrder.setOrderProductNum(1000);
    
                //2.2原来的订单保留,把数量设置成减少1000
                order.setOrderProductNum(order.getOrderProductNum()-1000);
    
                //然后是业务功能处理,省略了,打印输出,看一下
                System.out.println("拆分生成订单=="+newOrder);
            }
            //3:不超过,那就直接业务功能处理,省略了,打印输出,看一下
            System.out.println("订单=="+order);
        }
    }
    
  5. OrderClient

    public class OrderClient {
        public static void main(String[] args) {
           //创建订单对象,这里为了演示简单,直接new了
           PersonalOrder op = new PersonalOrder();
           //设置订单数据
           op.setOrderProductNum(2925);
           op.setCustomerName("张三");
           op.setProductId("P0001");
    
           //这里获取业务处理的类,也直接new了,为了简单,连业务接口都没有做
           OrderBusiness ob = new OrderBusiness();
           //调用业务来保存订单对象
           ob.saveOrder(op);
        }
    }
    
17.2 java中的原型模式
  1. java语言天生就将原型模式设计到了语言模型中

  2. Object类本身就带有clone方法,但该方法的权限为protected,所以一个类想在该类外部使用clone方法,必须重写该方法,从而扩大clone方法权限

  3. 同时类如果想使用Object的clone方法,还需要实现Cloneable接口

  4. j调用Object的clone方法,构造器不会被执行

  5. Object的clone方法只拷贝对象本身,不对其成员变量进行拷贝,只拷贝成员变量为基本类型以及String的那些

  6. 想被克隆的对象的成员变量,不能用final修饰

  7. 通常可以利用序列化与反序列化进行深复制

  8. PersonalOrder

//1. 必须实现Cloneable接口
public class PersonalOrder implements Cloneable , OrderApi{
  	//2. 重写Object的clone方法,以扩大使用范围
    public Object clone(){
       PersonalOrder obj=null;
       try {
         	//调用Object的clone方法
          obj =(PersonalOrder)super.clone();
          //Object的clone方法只拷贝对象本身,不对其成员变量进行拷贝,所以如果想进行深克隆,需要对引用类型成员变量进行特殊处理
          obj.setProduct((Product)this.product.clone());
       } catch (CloneNotSupportedException e) {
          e.printStackTrace();
       }     
       return obj;
    }
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值