上次我写道对象的名称非常重要,必须仔细选择它们并注意细节。 坏名吓坏了,不允许理解正在发生的事情的本质。 但是,这的本质是什么?
不了解英雄的“状态”和“能力”就很难评估英雄。 他能做的和他能做的是我们必须深入的下一个难度级别。 靠一个确切的名字来反映对象的内部保护区是不够的,您还需要确保这是相同的保护区 ,而不是来自吸气剂的马s。
关于此-在文章中。
循环目录
- 对象
- 动作和属性
- 文字编码
动作
角色攻击,防守,躲避,从弓箭射击,使用咒语,挥动剑刃。 名称反映了对象,但是对象本身在运动,反应,活动中。 否则,我们将讨论Excel中的表格。
在C#中,动作是方法和函数。 对于我们来说:动词,言语运动的原子。 动词会随着时间的流逝而运动,因为它们存在并相互作用。 有变化的地方-必须有动词。
二传手
在所有更改中,分配最少是所有可移动的。 它严格而数学地描述了数量是什么以及它们等于什么,但从未像动词那样向文本传达生命和活力。
例如,存在具有Status
属性的IPullRequest
,可以将其Approved
, Declined
或Merged
。 您可以编写pullRequest.Status = Status.Declined
,但这与说“将池请求设置为取消状态”相同,这是必须的。 pullRequest.Decline()
以及相应的pullRequest.Approve()
, pullRequest.Merge()
更强大。
主动动词比二传手更可取,但并非所有动词都可以。
被动语态
PerformPurchase
, DoDelete
, MakeCall
。
就像在HeroManager
一个重要的名词会被毫无意义的Manager
所遮盖,因此在PerformMigration
- Perform
中PerformMigration
如此。 毕竟,还活着-只需Migrate
!
主动动词刷新文本:不是“ hit” ,而是“ hit” ; 不是“摇摆” ,而是“挥手” ; 不是“决定” ,而是“决定” 。 因此在代码中: PerformApplication
→ Apply
; DoDelete
→ Delete
; PerformPurchase
→ Purchase
, Buy
。 (但 DealDamage
解决,尽管在极少数情况下,可能意味着 Attack
。)
避免被动语态,我们开发了故事,移动了角色,但我们还需要确保电影不以黑白显示。
强动词
有些词比其他词更好地表达了含义。 如果您写“他喝了一杯水” ,它将很简单明了。 但是“排干了一杯水” -比喻更坚固。
因此,玩家的健康状况变化可以通过player.Health = X
或player.Health = X
来表示,但更加生动的是player.RestoreHealth
。
或者,例如,我们不是通过Add/Remove
而是通过Push/Pop
了解Stack
。
如果动词不太具体,则强而有力的动词会使对象充满行为。
冗余部分
与ManualResetEvent
,我们越接近.NET的技术内部结构,这些结构就复杂了,只要简单地表达它们,API的细节和多余的内容就越丰富。
碰巧您需要在另一个线程上做一些工作,但是不要为创建和停止它而烦恼。 在C#中ThreadPool
于此的ThreadPool
。 这里只有一个简单的“工作” QueueUserWorkItem
! 不清楚工作项( WorkItem
)是什么类型,如果不是用户( User
)则可以是什么。 容易ThreadPool.Run
或ThreadPool.Execute
。
另一个例子。 记住并知道有一个原子比较和交换(CAS)指令是好的,但是将其干净地移植到代码中并不是最佳的解决方案。 Interlocked.CompareExchange(ref x, newX, oldX)
不如Interlocked.CompareExchange(ref x, newX, oldX)
Atomically.Change(ref x, from: oldX, to: newX)
(使用命名参数)。
该代码不是使用量子计算机的博士学位,也不是数学计算的应用程序,但读者有时对所谓的低级指令完全无所谓。 日常使用很重要。
重复次数
UsersRepository.AddUser
, Benchmark.ExecuteBenchmark
, AppInitializer.Initialize
, UniversalMarshaller.Marshal
, Logger.LogError
。
正如我在最后一部分中所述,重复会削弱含义,压缩空间。
不是UsersRepository.AddUser
,而是UsersRepository.Add
; 不是Directory.CreateDirectory
,而是Directory.Create
; 不是HttpWebResponse.GetResponseStream
,而是HttpWebResponse.Stream
; 不是Logger.LogError
,而是Log.Error
。
细垃圾
Check
是一个多方面的词。 如果用户的名称太长,则CheckHasLongName
可以返回bool
或引发异常。 更好的是bool HasLongName
或void EnsureHasShortName
。 我什至遇到了CheckRebootCounter
,它在里面的某个地方重新启动了IIS!
Enumerate
-来自同一系列。 在.NET中,有一个Directory.EnumerateDirectories(path)
方法:出于某种原因,尽管Directories.Of(path)
或path.Directories()
,但指定将列出文件夹。
Calc
尽管看起来更像钙沉积物,但通常减少Calculate
。
Proc
是Process
另一个花哨的缩写。
表示对象复杂性的Base
, Impl
, Internal
, Raw
寄生词。
合计
细心的读者会再次注意到,所有这些都归结为简化,自然语言的比喻,而且技巧本身不仅与代码有关,而且与一般编写有关。 通过使用它们,开发人员可以将代码既作为文本又作为文本本身进行修饰,以简化透明,平滑的外观。
现在我们已经弄清楚了运动和“特殊效果”,让我们看看如何描述对象之间的关系。
属性
角色有健康和法力; 物品在购物篮中; 太阳系由行星组成。 对象不仅会无私地行动,而且还会关联:层次结构(祖先继承人),结构化(整数部分),空间上(存储元素)等。
在C#中,属性和关系是方法(通常以Get
开头),getter(具有特定get
正文的属性)和字段。 但对我们而言,它是:单词加法,表示一个对象对另一个对象的归属。 例如,玩家的健康状况Player.Health
几乎与英语“玩家的健康状况”相对应。
今天最困惑的是动作方法和属性方法。
动词代替名词
GetDiscount
, CalculateDamage
, FetchResult
, ComputeFov
, CreateMap
。
解决方法无处不在:方法必须以动词开头。 您很少看到有人对此表示怀疑:这是真的吗? 毕竟, Player.Health
和Player.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
。
代码中的文字也有所不同,在第一种情况下,如果房子是站立的,淹没在夕阳的照耀下,您将获得报酬; 第二点-如果房子是站立的 ; 但是值得记住的是: 房子应该立起来,而不是被助手们粘住。
在本系列的前两篇文章中,我想展示不仅在算法上而且在单词上工作的重要性。 名称是如何确定所称内容的; 冗余和过于复杂的代码如何驱使读者离开。
除此之外,好名字只是笔记。 要播放 ,必须将它们写成音乐并体现出来。 我将在下一篇最后的文章中告诉您更多信息。