当前位置: 首页 > 科技观察

使用Option

时间:2023-03-17 15:53:54 科技观察

的正确姿势我们会经常使用Scala的Option来解决NullObject这样的问题。在某种程度上,使用Option必然会减少判断空指针引用的难看代码。结合ForComprehension,确实是Scala编程中的利器。在我的博客《引入Option优雅地保证健壮性》和《并非Null Object这么简单》中,我详细分析和介绍了Option的本质和应用。不过,Option虽好,我们也不能“贪”!从语义上讲,Option代表一个容器(Monad),它要么为空,要么存在。比如List的headOption就是对Option的合理解释。那么,只要是二态业务场景就可以使用Option吗?例如定义函数的参数类型为Option类型,表示用户对传递参数的选择:是否传递实际值。这是一个体面的姿态吗?DanielWestheide的博客文章WhenOptionIsNotGoodEnough明确表示不同意。他举了这样一个案例:根据商品名称和零售商信息查询Offer:defsearchOffers(productTitle:Option[String],retailer:Option[Retailer]):Seq[Offer]=???作为这个函数的调用者,应该如何大家看看这两个Option参数的业务含义?如果productTitle为None,是否代表忽略productTitle的值,只搜索满足零售商条件的offer;或搜索不提供productTitle的报价记录?同样,也传递了retailer参数如此模棱两可的意图!好的代码,尤其是界面,应该是“不言自明”的,清楚地传达开发者的意图。当涉及到具体的业务场景时,代码应该恰当、清晰地表达其业务含义。界面体现了一种准确无处不在的语言,这是DDD的核心价值。如果我们为这两个搜索条件定义表达业务含义的代数数据类型(algebraicdatatypes),如下代码所示,表意无疑要清晰许多:sealedtraitSearchCriteriaobjectSearchCriteria{finalcaseobjectMatchAllextendsSearchCriteriafinalcaseclassContains(s:String)extendsSearchCriteria}sealedtraitRetailerCriteriaobjectRetailerCriteria{finalcaseobjectAnyRetailerextendsRetailerCriteriafinalcaseclassOnly(retailer:Retailer)extendsRetailerCriteria}defsearchOffers(product:SearchCriteria,retailer:RetailerCriteria):Seq[Offer]=???Seq[Offer]=???SeqCriteriaandRetailerCriteriaaretwoqueryconditionsthatprovidetheirownquerysemantics,whichareobviouslyclearerthantheoverlyabstractSomeandNonereadable.Introducingsuchanalgebraicdatatypecannotonlymakethecodemoreclear,butalsobetterrespondtochangesinrequirements.FortheexistingSearchCriteriadefinition,ifyouwanttobefar-fetched,youcanindeedsaythat:MatchAllisthesemanticsofNone,andContainscorrespondstoSome.However,iftherequirementrequiresaddinganexactmatchingqueryscenario,howshouldweexpressitfortheOptiontype?GoingbacktothedefinitionofSearchCriteria,wecaneasilyaddatypeforit:objectSearchCriteria{finalcaseobjectMatchAllextendsSearchCriteriafinalcaseclassContains(s:String)extendsSearchCriteriafinalcaseclassExactly(s:String)extendsSearchCriteria}ComparedwithOption,itaddsanewtype,butitgreatlyimprovesthereadabilityofthecode,andalsolaysthefoundationforthefutureextensionofthecode.与获得的好处相比,增加新类型所付出的小代价根本不算什么!【本文为专栏作家“张艺”原创稿件,转载请联系原作者】点此阅读更多该作者好文