该代码是活的还是死的。 第二部分 动作和属性

上次我写道对象的名称非常重要,必须仔细选择它们并注意细节。 坏名吓坏了,不允许理解正在发生的事情的本质。 但是,这的本质是什么?


不了解英雄的“状态”“能力”就很难评估英雄。 他能做的和他能做的是我们必须深入的下一个难度级别。 靠一个确切的名字来反映对象的内部保护区是不够的,您还需要确保这是相同的保护区 ,而不是来自吸气剂的马s。


关于此-在文章中。


循环目录


  1. 对象
  2. 动作和属性
  3. 文字编码

动作


角色攻击,防守,躲避,从弓箭射击,使用咒语,挥动剑刃。 名称反映了对象,但是对象本身在运动,反应,活动中。 否则,我们将讨论Excel中的表格。


在C#中,动作是方法和函数。 对于我们来说:动词,言语运动的原子。 动词会随着时间的流逝而运动,因为它们存在并相互作用。 有变化的地方-必须有动词。


二传手


在所有更改中,分配最少是所有可移动的。 它严格而数学地描述了数量是什么以及它们等于什么,但从未像动词那样向文本传达生命和活力。


例如,存在具有Status属性的IPullRequest ,可以将其ApprovedDeclinedMerged 。 您可以编写pullRequest.Status = Status.Declined ,但这与说“将池请求设置为取消状态”相同,这是必须的。 pullRequest.Decline()以及相应的pullRequest.Approve()pullRequest.Merge()更强大。


主动动词比二传手更可取,但并非所有动词都可以。


被动语态


PerformPurchaseDoDeleteMakeCall


就像在HeroManager一个重要的名词会被毫无意义的Manager所遮盖,因此在PerformMigration - PerformPerformMigration如此。 毕竟,还活着-只需Migrate


主动动词刷新文本:不是“ hit” ,而是“ hit” ; 不是“摇摆” ,而是“挥手” ; 不是“决定” ,而是“决定” 。 因此在代码中: PerformApplicationApply ; DoDeleteDeletePerformPurchasePurchaseBuy(但 DealDamage 解决,尽管在极少数情况下,可能意味着 Attack 。)


避免被动语态,我们开发了故事,移动了角色,但我们还需要确保电影不以黑白显示。


强动词


有些词比其他词更好地表达了含义。 如果您写“他喝了一杯水” ,它将很简单明了。 但是“排干了一杯水” -比喻更坚固。


因此,玩家的健康状况变化可以通过player.Health = Xplayer.Health = X来表示,但更加生动的是player.RestoreHealth


或者,例如,我们不是通过Add/Remove而是通过Push/Pop了解Stack


如果动词不太具体,则强而有力的动词会使对象充满行为。


冗余部分


ManualResetEvent ,我们越接近.NET的技术内部结构,这些结构就复杂了,只要简单地表达它们,API的细节和多余的内容就越丰富。


碰巧您需要在另一个线程上做一些工作,但是不要为创建和停止它而烦恼。 在C#中ThreadPool于此的ThreadPool 。 这里只有一个简单的“工作” QueueUserWorkItem ! 不清楚工作项( WorkItem )是什么类型,如果不是用户( User )则可以是什么。 容易ThreadPool.RunThreadPool.Execute


另一个例子。 记住并知道有一个原子比较和交换(CAS)指令是好的,但是将其干净地移植到代码中并不是最佳的解决方案。 Interlocked.CompareExchange(ref x, newX, oldX)不如Interlocked.CompareExchange(ref x, newX, oldX) Atomically.Change(ref x, from: oldX, to: newX) (使用命名参数)。


该代码不是使用量子计算机的博士学位,也不是数学计算的应用程序,但读者有时对所谓的低级指令完全无所谓。 日常使用很重要。


重复次数


UsersRepository.AddUserBenchmark.ExecuteBenchmarkAppInitializer.InitializeUniversalMarshaller.MarshalLogger.LogError


正如我在最后一部分中所述,重复会削弱含义,压缩空间。


不是UsersRepository.AddUser ,而是UsersRepository.Add ; 不是Directory.CreateDirectory ,而是Directory.Create ; 不是HttpWebResponse.GetResponseStream ,而是HttpWebResponse.Stream ; 不是Logger.LogError ,而是Log.Error


细垃圾


Check是一个多方面的词。 如果用户的名称太长,则CheckHasLongName可以返回bool或引发异常。 更好的是bool HasLongNamevoid EnsureHasShortName 。 我什至遇到了CheckRebootCounter ,它在里面的某个地方重新启动了IIS!


Enumerate -来自同一系列。 在.NET中,有一个Directory.EnumerateDirectories(path)方法:出于某种原因,尽管Directories.Of(path)path.Directories() ,但指定将列出文件夹。


Calc尽管看起来更像钙沉积物,但通常减少Calculate


ProcProcess另一个花哨的缩写。


表示对象复杂性的BaseImplInternalRaw寄生词。


合计


细心的读者会再次注意到,所有这些都归结为简化,自然语言的比喻,而且技巧本身不仅与代码有关,而且与一般编写有关。 通过使用它们,开发人员可以将代码既作为文本又作为文本本身进行修饰,以简化透明,平滑的外观。


现在我们已经弄清楚了运动和“特殊效果”,让我们看看如何描述对象之间的关系。


属性


角色有健康和法力; 物品在购物篮中; 太阳系由行星组成。 对象不仅会无私地行动,而且还会关联:层次结构(祖先继承人),结构化(整数部分),空间上(存储元素)等。


在C#中,属性和关系是方法(通常以Get开头),getter(具有特定get正文的属性)和字段。 但对我们而言,它是:单词加法,表示一个对象对另一个对象的归属。 例如,玩家的健康状况Player.Health几乎与英语“玩家的健康状况”相对应。


今天最困惑的是动作方法和属性方法。


动词代替名词


GetDiscountCalculateDamageFetchResultComputeFovCreateMap


解决方法无处不在:方法必须以动词开头。 您很少看到有人对此表示怀疑:这是真的吗? 毕竟, Player.HealthPlayer.Health()之间不会有显着差异。 让记录在语法上有所不同,它们意味着同一件事。


假设在IUsersRepository中很容易期望有一些GetUser(int id) 。 为什么要代表用户考虑某种收据( Get )? 它将更加准确- User(int id)


实际上:不是FetchResult() ,而是Result() ; 不是GetResponse() ,而是Response() ; 不是CalculateDamage() ,而是Damage()


一个DDD演讲给出了一个“好”代码的示例:具有CalculateDiscountBy(int customerId)方法的DiscountCalculator 。 不仅在脸上有一个对称的重复DiscountCalculator.CalculateDiscount ,而且他们还指定了折扣的计算 。 还有人问她要做什么?


从实体本身出发-带有static decimal Of(Customer customer, Order order)方法的Discount.Of(customer, order)调用Discount.Of(customer, order) -比_discountCalculator.CalculateDiscountBy(customerId)更简单,并且对应于一种语言。


有时,省略动词会丢失一些内容,例如在CreateMap() :用Map()直接替换可能不够。 然后最好的解决方案是NewMap() :同样,对象在NewMap() ,而不是动作。


使用空的空动词是过时的命令式文化的特征,其中算法是主要的,并且领先于概念。 在这里,您经常会发现“已回火的刀片”而不是“硬化的刀片” 。 但是有关詹姆斯·邦德的书籍的风格并不适合描述风景。 没有动静的地方,动词就没有位置。


其他


表达对象之间的关系的属性和方法也是对象,因此,上述内容在许多方面都适用于它们。


例如,属性中的重复:不是Thread.CurrentThread ,而是Thread.Current ; 不是Inventory.InventoryItems ,而是Inventory.Items等。


合计


简单易懂的单词不会混淆,因此由它们组成的代码也不会混淆。 在写作中,轻松写作同样重要:避免被动介词,大量副词和形容词,重复项,因为动作比名词更喜欢动词。 一个著名的例子: “他点了头,同意了”,而不是“他点了点头”,引起了微笑,我记得QueueUserWorkItem


代码中的文字也有所不同,在第一种情况下,如果房子是站立的,淹没在夕阳的照耀下,您将获得报酬; 第二点-如果房子是站立的 ; 但是值得记住的是: 房子应该立起来,而不是被助手们粘住。


在本系列的前两篇文章中,我想展示不仅在算法上而且在单词上工作的重要性。 名称是如何确定所称内容的; 冗余和过于复杂的代码如何驱使读者离开。


除此之外,好名字只是笔记。 要播放 ,必须将它们写成音乐并体现出来。 我将在下一篇最后的文章中告诉您更多信息。

Source: https://habr.com/ru/post/zh-CN447674/


All Articles