范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

华为技术专家教你重构代码将值对象改为引用对象

  动机
  一个数据结构中可能包含多个记录,而这些记录都关联到同一个逻辑数据结构。例如,我可能会读取一系列订单数据,其中有多条订单属于同一个顾客。遇到这样的共享关系,既能将顾客信息作为值对象看待,也能将其视为引用对象: 若将其视为值对象,则每份订单数据中都会复制顾客的数据 若将其视为引用对象,对于一个顾客,就只有一份数据结构,会有多个订单与之关联
  若顾客数据永不修改,则两种方式都合理。 把同一份数据复制多次可能会造成一点困扰,但这种情况也
  很常见,不是太大问题。过多的数据复制有可能会造成内存占用的问题,但就跟所有性能问题一样,这种情况并不常见。
  若共享的数据需要更新,将其复制多份的做法就会遇到巨大困难。此时我必须找到所有副本,更新所有对象。漏掉一个副本没更新,就会导致数据不一致。这时,考虑将多份数据副本变成单一的引用,这样对顾客数据的修改就会立即反映在该顾客的所有订单中。
  把值对象改为引用对象会带来一个结果:对于一个客观实体,只有一个代表它的对象。这通常意味着我会需要某种形式的仓库,在仓库中可以找到所有这些实体对象。只为每个实体创建一次对象,以后始终从仓库中获取该对象。 做法
  为相关对象创建一个仓库(若还没这样的一个仓库)。 确保构造器有办法找到关联对象的正确实例。修改宿主对象的构造器,令其从仓库中获取关联对象。每次修改后测试。 案例
  订单Order类,其实例对象可从一个JSON文件创建。用来创建订单的数据中有一个顾客(customer)ID,我们用它来进一步创建Customer对象。  package com.javaedge.refactor.ttt;    import lombok.AllArgsConstructor;  import lombok.Getter;    import java.math.BigDecimal;  import java.util.Objects;    /**   * @author JavaEdge   * @date 2022/4/1   */  @Getter  public class Order {            private Customer customer;        public Order(String customerName) {          customer = new Customer(customerName);      }        public String getCustomerName() {          return customer.getName();      }        void setCustomerName(String customerName) {          customer = new Customer(customerName);      }    }
  此外,还有一些代码也会使用 *Customer* 对象;  package com.javaedge.refactor.ttt;    import lombok.Getter;    import java.util.Collection;    /**   * @author JavaEdge   * @date 2022/4/1   */  @Getter  public class Order {        private Customer customer;        public Order(String customerName) {          customer = new Customer(customerName);      }        public String getCustomerName() {          return customer.getName();      }        void setCustomerName(String customerName) {          customer = new Customer(customerName);      }        private static int numberOfOrdersFor(Collection orders, String customer) {          int result = 0;            for (Order each : orders) {              if (each.getCustomerName().equals(customer)) {                  result++;              }          }          return result;      }  }
  到目前为止,Customer对象还是值对象。就算多份订单属于同一客户,但每个 *Order* 对象还是拥有各自的 *Customer* 对象。我希望改变这现状,使得一旦同一客户拥有多份不同订单,代表这些订单的所有 *Order* 对象就能共享同一个Customer对象。本例中,就意味着: 每 一个客户名称只该对应一个Customer对象。
  首先我使用  Replace Constructor with Factory Method ,控制  *Customer* 对象的创建过程。我在 *Customer* 中定义工厂方法:  package com.javaedge.refactor.ttt;    import lombok.AllArgsConstructor;  import lombok.Getter;    /**   * @author JavaEdge   * @date 2022/4/1   */  @Getter  @AllArgsConstructor  class Customer {        private String name;        public static Customer create(String name) {          return new Customer(name);      }  }
  然后把原本调用构造函数的地方改为调用工厂函数:
  然后再把构造函数声明为private:  package com.javaedge.refactor.ttt;    import lombok.AllArgsConstructor;  import lombok.Getter;    /**   * @author JavaEdge   * @date 2022/4/1   */  @Getter  class Customer {        private String name;        private Customer(String name) {          this.name = name;      }        public static Customer create(String name) {          return new Customer(name);      }  }
  现在,我必须决定如何访问Customer对象。我比较喜欢通过另一个对象(例如Order中的一个字段)来访问它。但本例并没有这样一个明显的字段用于访问Customer对象。
  这时,我通常会创建一个注册表对象来保存所有Customer对象,以此作为访问点。简化例子,我把这个注册表保存在Customer类的static字段中,让Customer类作为访问点:
  然后我得决定: 在接到请求时,创建新的Customer对象 还是预先将它们创建好
  这里我选择后者。在应用程序的启动代码中,先把需要使用的Customer对象加载妥当。这些对象可能来自数据库,也可能来自文件。简单起见,我在代码中明确生成这些对象。反正以后我总是可以使用Substitute Algorithm改变它们的创建方式。  package com.javaedge.refactor.ttt;    import lombok.AllArgsConstructor;  import lombok.Getter;    import java.util.Dictionary;  import java.util.HashMap;  import java.util.Map;    /**   * @author JavaEdge   * @date 2022/4/1   */  @Getter  class Customer {        private String name;        private static Map instances = new HashMap<>();            private Customer(String name) {          this.name = name;      }        public static Customer create(String name) {          return new Customer(name);      }        static void loadCustomers() {          new Customer("Java").store();          new Customer("Edge").store();          new Customer("公众号").store();      }        private void store() {          instances.put(this.getName(), this);      }  }
  修改工厂函数,让它返回预先创建好的Customer对象  package com.javaedge.refactor.ttt;    import lombok.AllArgsConstructor;  import lombok.Getter;    import java.util.Dictionary;  import java.util.HashMap;  import java.util.Map;    /**   * @author JavaEdge   * @date 2022/4/1   */  @Getter  class Customer {        private String name;        private static Map instances = new HashMap<>();        private Customer(String name) {          this.name = name;      }        public static Customer create(String name) {          return instances.get(name);      }        static void loadCustomers() {          new Customer("Java").store();          new Customer("Edge").store();          new Customer("公众号").store();      }        private void store() {          instances.put(this.getName(), this);      }  }
  由于create()总是返回既有的Customer对象,所以我应该使用Rename Method修改这个工厂函数的名称,以便强调这点:  public static Customer getNamed(String name) {    return instances.get(name);  }

爱玛雅迪金彭推出3款休闲三轮车,节能省电跑更远,适合接娃请您在阅读前,先点击上面的关注。感谢您的支持,我们将为您带来更多有价值的内容。作为休闲三轮车领域的三巨头爱玛雅迪金彭自今年以来就相继推出了不少休闲三轮车产品,主打节能省电跑更远的产滴滴总裁柳青辞职跑路?滴滴面临联合审查已经有一段时间了,但到目前为止还没有正式的结果发布,关于滴滴公司的猜测越来越多,滴滴事件逐渐被蒙上了一层阴影,一时间各种说法不绝于耳。滴滴成长可以说是奇迹,要想从众ansible的使用和安装一ansible入门1。介绍Ansible是一种IT自动化工具。它可以配置系统,部署软件以及协调更高级的IT任务,例如持续部署,滚动更新。Ansible适用于管理企业IT基础设施,MySQLinnodb引擎深入讲解一逻辑存储结构表空间(ibd文件),一个MySQL实例可以对应多个表空间,用于存储记录,索引等数据。段,分为数据段索引段回滚段,innodb是索引组织表,数据段就是BTree的叶子OPPOReno7跌至2299元了,它跟红米K50Pro相比,买哪款好?红米K50Pro和OPPOReno7并不是一个定位的产品,不论受众还是日常使用的定位都是不一样的。再者,红米K50系列是今年3月份发布的手机,整体配置都要比OPPORneo7高不少iPhone15概念机苹果首次采用屏下镜头,这样的真全屏有多豪横?苹果手机毫无疑问是目前市场上最受欢迎的手机,之所以销量好不仅是果粉的忠诚度非常高,最主要的原因还是手机质量好,用户体验相当不错。即便过去几年延续丑刘海的造型,但丝毫没有影响销量。今苹果库克伤心欲绝!是什么三星顶级A屏让国内旗舰抢着用?屏幕可以说是一台手机的门面,只要我们使用手机,几乎就需要时刻盯着这块能够发光的显示屏。单论屏幕素质这方面,三星可以说是全球顶级屏幕制造者!但是三星屏幕也有这等级之分,近期一款三星E准备告别,一代神机IPhone11即将落下帷幕,IPhone12也会降价IPhone13都要上市一年了,三年前的IPhone11还在生产,苹果似乎一点也没有想要为IPhone11下架的兆头,因为它现在仍然是与各大安卓厂商竞争的有力入门级手机产品。好景总清凉盛夏,几素桌面风扇相伴入夏,加倍快乐也不知从何时起,春天已悄然过半,花已开,天已凉。空气中盛夏的气息伴随春风悄悄地到来,讨厌夏天的热但也喜欢夏日清凉的感觉。在网上不经意间刷到了桌面版小风扇,为了让自己可以最多地感受夏iPhone14Pro最新消息,除了采用挖孔屏,还有小惊喜谈到iPhone14系列手机,相信大家最近看到了不少相关的爆料,虽说在手机正式发布之前这些内容都没什么太大用处,但是对于喜欢追新或者关注产品新动态的人来说,这类爆料信息始终会吸引着集体抵制一口价,这一次网约车司机赢了据全国网约车监管信息交互平台统计的数据显示,今年4月份,全国网约车订单量仅为4。76亿。相比2021年4月份网约车7。6亿的订单量,下降近3亿单。在行业订单严重下滑的情况下,网约车
iOS15更新发现,更智能iOS15更新发现,更智能关注公众号果粉机帮助果粉们快速成长Apple今天向果粉开发者发布了一款全新的开发工具,完全需要运行在iOS15的设备上,果粉在不安全的WiFi网络上或Wi摩托罗拉MotoG60S发布搭载HelioG95,支持50W快充IT之家8月12日消息今天,摩托罗拉新机MotoG60S在该公司的巴西网站上线,这也是该机全球首次亮相。摩托G60S配备了6。8英寸FHD120Hz屏幕,搭载联发科HelioG95为什么说摩托罗拉edge双新机是不妥协的诚意之作8月5日,摩托罗拉在上海举行了新品发布会,宣布推出Edge双新机edgespro和edge轻奢版。一强悍配置不妥协,摩托罗拉edge双新机惊艳亮相本场发布会的主题为亿起惊艳,而其推vivoS10在这个夏季惊喜上市啦藏不住的自然美陕西篇vivoS10在这个夏季惊喜上市啦!不但质感很轻薄,颜值也是绝绝子!集美们一定要闭眼入呀这款作为蔡徐坤同款手机,还引入了最新的光致变色技术,一晒阳光还可以变色哦性价比较高的安卓二手机我就给大家介绍一些性价比较高的安卓二手机,因为毕竟人人都不是手机发烧友,买的洋垃圾不一定会捣鼓。50以下小米2s,几顿早餐钱就能带走一部能听歌看小说的手机。这部手机搭载高通骁龙60三星GalaxyZFlip35G亮相设计配置全方位升级,体验无死角2020年,三星推出了旗下全新的折叠屏产品GalaxyZFlip系列,纵向折叠的全新形态,搭配上UTG超薄玻璃的内屏材质,给折叠屏的发展提出了一个新的思路。如今,三星旗下第三代折叠三星新品折叠手机支持防水?8月11日,三星举行新品发布会,推出了两款折叠屏智能手机GalaxyZFold35G和GalaxyZFlip35G。三星对折叠屏手机市场非常看好,其公布一组数据,折叠屏市场正以年增鸿蒙2。0系统更新后,你不知道的5个手机技巧,真的可惜我们都知道,这两年华为的热度只增不减,自鸿蒙系统的出现,再一次让华为的热度大大提高,前段时间的鸿蒙2。0系统更新,更是传的沸沸扬扬,我相信照这个趋势,鸿蒙之后的系统更新一定会受到华七夕男友礼物选什么?懂行的人今年都选这几款手机1,小米MIX4这是小米刚刚发布的今年的旗舰手机,4999的价格对于这顶配旗舰来说划算合理,全球首发的骁龙888plus处理器加上CUP全面屏,在手机性能和使用感受上体验拉满了!同七夕节,送女朋友这几款手机,她肯定会喜欢对手机这一类数码产品比较感兴趣的一般男生居多,而女生则对手机这类数码产品了解比较少,她们最常使用的功能是拍照片(包括自拍),看电视剧,玩游戏,聊天社交,同时颜值在线,手感要好,要够麦芒系列正式回归,脱离华为后,麦芒10SE终于支持5G哈喽大家好,我是你们的老朋友小馨,每天都会给大家更新我的原创内容,近日,曾作为华为旗下的麦芒系列品牌,如今却带来了一款5G千元机麦芒10SE,这款起售价为1699元的新品,搭载了一