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

聊聊软件开发的SLAP原则

  序
  本文主要研究一下软件开发的SLAP(Single Level of Abstraction Principle)原则 SLAP
  SALP即Single Level of Abstraction Principle的缩写,即单一抽象层次原则。 在Robert C. Martin的<>一书中的函数章节有提到:
  要确保函数只做一件事,函数中的语句都要在同一抽象层级上。函数中混杂不同抽象层级,往往让人迷惑。读者可能无法判断某个表达式是基础概念还是细节。更恶劣的是,就像破损的窗户,一旦细节与基础概念混杂,更多的细节就会在函数中纠结起来。
  这与  Don"t Make Me Think[1]  有异曲同工之妙,遵循SLAP的代码通常阅读起来不会太费劲。
  另外没有循序这个原则的通常是 Leaky Abstraction[2]
  要遵循这个原则通常有两个好用的手段便是抽取方法与抽取类。 实例1public List buildResult(Set resultSet) {     List result = new ArrayList<>();     for (ResultEntity entity : resultSet) {         ResultDto dto = new ResultDto();         dto.setShoeSize(entity.getShoeSize());                 dto.setNumberOfEarthWorms(entity.getNumberOfEarthWorms());         dto.setAge(computeAge(entity.getBirthday()));         result.add(dto);     }     return result; }
  这段代码包含两个抽象层次,一个是循环将resultSet转为  List  ,一个是转换ResultEntity到ResultDto
  可以进一步抽取转换ResultDto的逻辑到新的方法中 public List buildResult(Set resultSet) {     List result = new ArrayList<>();     for (ResultEntity entity : resultSet) {         result.add(toDto(entity));     }     return result; }  private ResultDto toDto(ResultEntity entity) {     ResultDto dto = new ResultDto();     dto.setShoeSize(entity.getShoeSize());             dto.setNumberOfEarthWorms(entity.getNumberOfEarthWorms());     dto.setAge(computeAge(entity.getBirthday()));     return dto; }
  这样重构之后,buildResult就很清晰  实例2public MarkdownPost(Resource resource) {         try {             this.parsedResource = parse(resource);             this.metadata = extractMetadata(parsedResource);             this.url = "/" + resource.getFilename().replace(EXTENSION, "");         } catch (IOException e) {             throw new RuntimeException(e);         }     }
  这里的url的拼装逻辑与其他几个方法不在一个层次,重构如下  public MarkdownPost(Resource resource) {         try {             this.parsedResource = parse(resource);             this.metadata = extractMetadata(parsedResource);             this.url = urlFor(resource);         } catch (IOException e) {             throw new RuntimeException(e);         } }  private String urlFor(Resource resource) {         return "/" + resource.getFilename().replace(EXTENSION, ""); }实例3public class UglyMoneyTransferService  {     public void transferFunds(Account source,                                Account target,                                BigDecimal amount,                                boolean allowDuplicateTxn)                           throws IllegalArgumentException, RuntimeException      {         Connection conn = null;     try {         conn = DBUtils.getConnection();         PreparedStatement pstmt =              conn.prepareStatement("Select * from accounts where acno = ?");         pstmt.setString(1, source.getAcno());         ResultSet rs = pstmt.executeQuery();         Account sourceAccount = null;         if(rs.next()) {             sourceAccount = new Account();             //populate account properties from ResultSet         }         if(sourceAccount == null){             throw new IllegalArgumentException("Invalid Source ACNO");         }         Account targetAccount = null;         pstmt.setString(1, target.getAcno());         rs = pstmt.executeQuery();         if(rs.next()) {             targetAccount = new Account();             //populate account properties from ResultSet         }         if(targetAccount == null){             throw new IllegalArgumentException("Invalid Target ACNO");         }         if(!sourceAccount.isOverdraftAllowed()) {             if((sourceAccount.getBalance() - amount) < 0) {                 throw new RuntimeException("Insufficient Balance");             }         }         else {             if(((sourceAccount.getBalance()+sourceAccount.getOverdraftLimit()) - amount) < 0) {                 throw new RuntimeException("Insufficient Balance, Exceeding Overdraft Limit");             }         }         AccountTransaction lastTxn = .. ; //JDBC code to obtain last transaction of sourceAccount         if(lastTxn != null) {             if(lastTxn.getTargetAcno().equals(targetAccount.getAcno()) && lastTxn.getAmount() == amount && !allowDuplicateTxn) {             throw new RuntimeException("Duplicate transaction exception");//ask for confirmation and proceed             }         }         sourceAccount.debit(amount);         targetAccount.credit(amount);         TransactionService.saveTransaction(source, target,  amount);     }     catch(Exception e){         logger.error("",e);     }     finally {         try {              conn.close();          }          catch(Exception e){              //Not everything is in your control..sometimes we have to believe in GOD/JamesGosling and proceed         }     } }     }
  这段代码把dao的逻辑泄露到了service中,另外校验的逻辑也与核心业务逻辑耦合在一起,看起来有点费劲,按SLAP原则重构如下  class FundTransferTxn {     private Account sourceAccount;      private Account targetAccount;     private BigDecimal amount;     private boolean allowDuplicateTxn;     //setters & getters }  public class CleanMoneyTransferService  {     public void transferFunds(FundTransferTxn txn) {         Account sourceAccount = validateAndGetAccount(txn.getSourceAccount().getAcno());         Account targetAccount = validateAndGetAccount(txn.getTargetAccount().getAcno());         checkForOverdraft(sourceAccount, txn.getAmount());         checkForDuplicateTransaction(txn);         makeTransfer(sourceAccount, targetAccount, txn.getAmount());     }      private Account validateAndGetAccount(String acno){         Account account = AccountDAO.getAccount(acno);         if(account == null){             throw new InvalidAccountException("Invalid ACNO :"+acno);         }         return account;     }      private void checkForOverdraft(Account account, BigDecimal amount){         if(!account.isOverdraftAllowed()){             if((account.getBalance() - amount) < 0)    {                 throw new InsufficientBalanceException("Insufficient Balance");             }         }         else{             if(((account.getBalance()+account.getOverdraftLimit()) - amount) < 0){                 throw new ExceedingOverdraftLimitException("Insufficient Balance, Exceeding Overdraft Limit");             }         }     }      private void checkForDuplicateTransaction(FundTransferTxn txn){         AccountTransaction lastTxn = TransactionDAO.getLastTransaction(txn.getSourceAccount().getAcno());         if(lastTxn != null)    {             if(lastTxn.getTargetAcno().equals(txn.getTargetAccount().getAcno())                      && lastTxn.getAmount() == txn.getAmount()                      && !txn.isAllowDuplicateTxn())    {                 throw new DuplicateTransactionException("Duplicate transaction exception");             }         }     }      private void makeTransfer(Account source, Account target, BigDecimal amount){         sourceAccount.debit(amount);         targetAccount.credit(amount);         TransactionService.saveTransaction(source, target,  amount);     }     }
  重构之后transferFunds的逻辑就很清晰,先是校验账户,再校验是否超额,再校验是否重复转账,最后执行核心的makeTransfer逻辑  小结
  SLAP与  Don"t Make Me Think[3]  有异曲同工之妙,遵循SLAP的代码通常阅读起来不会太费劲。另外没有循序这个原则的通常是Leaky Abstraction[4] 。doc
  • Clean Code - Single Level Of Abstraction[5]
  • Clean Code: Don’t mix different levels of abstractions[6]
  • Single Level of Abstraction (SLA)[7]
  • The Single Level of Abstraction Principle[8]
  • SLAP Your Methods and Don"t Make Me Think![9]
  • Levels of Abstraction[10]
  • Maintain a Single Layer of Abstraction at a Time | Object-Oriented Design Principles w/ TypeScript[11]
  • 聊一聊SLAP:单一抽象层级原则[12]
  外部链接
  [1]  Don"t Make Me Think   https://book.douban.com/subject/1440223/
  [2]  Leaky Abstraction   https://khalilstemmler.com/wiki/leaky-abstraction/
  [3]  Don"t Make Me Think   https://book.douban.com/subject/1440223/
  [4]  Leaky Abstraction   https://khalilstemmler.com/wiki/leaky-abstraction/
  [5]  Clean Code - Single Level Of Abstraction   https://www.c-sharpcorner.com/article/clean-code-single-level-of-abstraction/
  [6]  Clean Code: Don’t mix different levels of abstractions   https://www.sivalabs.in/2013/12/clean-code-dont-mix-different-levels-of-abstractions/
  [7]  Single Level of Abstraction (SLA)   http://principles-wiki.net/principles:single_level_of_abstraction
  [8]  The Single Level of Abstraction Principle   https://dzone.com/articles/the-single-level-of-abstraction-principle
  [9]  SLAP Your Methods and Don"t Make Me Think!   https://dzone.com/articles/slap-your-methods-and-dont-make-me-think
  [10]  Levels of Abstraction   https://dzone.com/articles/levels-of-abstraction
  [11]  Maintain a Single Layer of Abstraction at a Time | Object-Oriented Design Principles w/ TypeScript   https://khalilstemmler.com/articles/oop-design-principles/maintain-a-single-layer-of-abstraction/
  [12]  聊一聊SLAP:单一抽象层级原则   https://droidyue.com/blog/2019/03/17/slap-single-level-of-abstraction-principle/

京东面试官讲讲Redis各个数据类型的底层数据结构前段时间有朋友面试京东的时候,遇到这样的面试题。讲讲Redis的数据类型以及其对应的底层数据结构那么今天指北君带大家了解一下Redis基本数据类型对应的底层数据结构。1。前言RedDateUtils日期工具类日期相差集合(可改写,比如两个时间段,相差年,月,日,时,分,秒)return集合数据privateListStringprocessDateBetweenHourList()当前全球超5万名参赛者挑战这场数学竞赛年龄最小仅7岁浙江新闻客户端记者祝梅经过一个月的阅卷,5月23日,2022阿里巴巴全球数学竞赛在达摩院官网公布预选赛赛题及答案。记者获悉,本轮预选赛共吸引全球5万余名数学爱好者报名参赛,相关成绩技术GoogleMap干掉倾斜摄影了?相信这两天大家朋友圈都被GoogleMap新功能演示刷屏了,视频中介绍说GoogleMap将在一些城市实现实景渲染,在手机中能够就从不同视角能逼真地浏览城市场景,甚至还能实现从室外哔哩哔哩推出PC客户端后将UWP应用从微软商店下架前几天B站在PC上推出了客户端,有哪些朋友抢先体验过了呢?其实在正儿八经的客户端上线前,就已经存在UWP版本,有不少PC用户使用,尤其是Xbox玩家将其安装到Xbox上直接秒变机顶索尼CEOPSN月活跃用户达1亿收入达到140亿美元索尼集团首席执行官吉田宪一郎在最近的企业战略会议上透露了一些有趣的数字。PlayStationNetwork拥有超过1亿月活跃用户,销售额总计超过140亿美元,自2017年以来增长华测导航研究报告乘风破浪,华测导航四问四答(报告出品方作者长江证券,于海宁,黄天佑,祖圣腾,李烨)股价复盘公司历年涨跌原因是什么?公司发展史波澜壮阔的行业缩影华测导航是国内高精度卫星导航领域龙头厂商。公司成立于2003年,清退无证司机差0。01,平台着急填上运力漏洞,网友亡羊补牢?渐渐明朗的网约车合规化形势,把无证单证司机从幻想拉回现实,应该是不能继续跑下去了,否则就是自讨苦吃。出行市场竞争激烈,T3出行曹操出行一喂顺风车等平台不敢掉以轻心,生怕迟迟上不去的你的包裹由菜鸟守护,让更稳更快更好更绿成为可能面对疫情冲击,今年618大促的物流包裹能平稳送达吗?菜鸟给出的回答是肯定的。虽然现在疫情充满不确定性,但菜鸟一直在不确定性中寻找确定性,给商家和消费者更安心的守护。今日,菜鸟宣布启运营商纷纷成立数字科技公司背后,产业数字化业务的美丽与哀愁中国电信此次成立智能科技分公司,是争做核心技术自主掌控的科技型企业的重要举措之一,将加快推动公司大数据和AI核心能力建设,进一步强化公司科技创新能力。日前,中国电信宣布成立了自家的重磅!补贴政策或再度延长!电动知家消息,据路透社报道,目前国家工信部等多个部委,正与汽车制造商们就延长新能源汽车补贴问题进行会谈。目的是保持这个关键市场的增长。不过中国2023年延期的全部条款,包括补贴金额
无人版滴滴就要来了,国内首款低成本无人驾驶摆渡车将于年内实现量产无需司机,乘客通过手机APP一键叫车,车辆自己开到指定地点接客,再将乘客送往目的地。解放日报上观新闻记者获悉,近日,中科院合肥技术创新工程院智能移动机器人中心技术团队攻克了无人驾驶这些功能设计,微信走心了作为一个日活超10亿的社交产品,微信的每一个功能改版都要经受海量用户的检验。所以,微信的每一个功能的设计周期都会很长。他们对于功能的打磨的细腻与走心,从本文笔者举出的这两个例子就能苏宁菜场4月底上线,24小时内送至苏宁小店,盒马美团罗森均已入局4月3日,AI财经社获悉,苏宁小店将于4月下旬上线苏宁菜场。据悉,苏宁菜场计划24小时内将蔬菜从原产地发货至苏宁小店门店,主要针对蔬菜鲜肉豆制品活鱼(现杀)等商品。同时,苏宁小店A华为主动放弃默认4K模式,不把DxO分数作为目标集微网消息(文数码控),华为的P30Pro上个月在法国发布,它以112的综合成绩理所当然的拿下了DxOMark榜单的第一名,但是它的视频录制分数却只有97分,相较于上一代的P20P锤子新品将至?坚果手机开始补货在聊天宝发布会后,锤子科技罗永浩基本很少在公众露面,截止到现在已经有近3个月时间。不仅如此,锤子科技情况百出,高管集体退出全部机型官网无货被今日头条收购等等,而对于这些消息,罗永浩微信这一功能不关闭,隐私会一直泄露,许多人都没发现!在去年微信更新大版本7。0后,公众号文章右下角的点赞升级为了好看,同时在微信看一看功能中,为好看提供了一个专属的模块,只要你点了好看,好看板块就会显示你观看过的文章。而最近,微信则章泽天卸任,是偶然还是必然?重庆嫩绿茶艺有限公司的董事变更引起网友的各种猜想,原因很简单,因为变更的人是京东老大刘强东的夫人奶茶妹妹章泽天。章泽天卸任这仅仅是普通的人事变动?还是刻意而为之?根据调查,章泽天此在闲鱼上看到有卖坏CPU的,几十块钱一个,那买家用来干嘛呢?CPU能修好吗?在某宝上卖的坏CPU一般会标注仅用于学术交流教学收藏和研究,而且销量还不错,这些坏的CPU到底有什么用呢?不禁让我想到了今年315晚会的家电维修问题。随着科技的进步,硬件市场应透明10个Python图像编辑工具以下提到的这些Python工具在编辑图像操作图像底层数据方面都提供了简单直接的方法。ParulPandey当今的世界充满了数据,而图像数据就是其中很重要的一部分。但只有经过处理和分中国黑客界鬼才,他写的病毒五年才能彻底清理,如今已经回归正道很多高科技的犯罪分子成为了一个世界性的难题,黑客就是这样的一个存在。他们只要动动手指就可以进入大家的电脑,甚至还能入侵现在的智能家居,安装智能摄像头,而且还能通过一些漏洞控制摄像头明年iPhone尺寸大改,5G难产据Digitimes报道,苹果近期正在制定2020年新iPhone的屏幕规格。与2019年相比,苹果2020年要推出的三款iPhone在尺寸上有了较大变动。Digitimes援引供