-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
2311 lines (2175 loc) · 110 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<html lang="en">
<head>
<title>Naming Things | Ka Wai Cheung</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Fredericka+the+Great|Lora:400,400i,700,700i|Roboto+Mono&display=swap" rel="stylesheet">
<link href="styles.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="donedone.ico" type="image/x-icon" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div class="menu">
<a href="">
<svg height="32px" id="Layer_1" style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M4,10h24c1.104,0,2-0.896,2-2s-0.896-2-2-2H4C2.896,6,2,6.896,2,8S2.896,10,4,10z M28,14H4c-1.104,0-2,0.896-2,2 s0.896,2,2,2h24c1.104,0,2-0.896,2-2S29.104,14,28,14z M28,22H4c-1.104,0-2,0.896-2,2s0.896,2,2,2h24c1.104,0,2-0.896,2-2 S29.104,22,28,22z"/>
</svg>
</a>
</div>
<div class="toc" id="toc">
<a href="" class="close-btn">×</a>
<div class="toc-content">
<h3>Naming Things</h3>
<a href="#ch-introduction">Introduction</a>
<a href="#ch-imagining-objects">Imagining Objects</a>
<a href="#ch-name-hunting">Name Hunting</a>
<a href="#ch-breaking-methods-apart">Breaking Methods Apart</a>
<a href="#ch-shape-of-code">The Shape of Code</a>
<a href="#ch-when-opposites-confuse">When Opposites Confuse</a>
<a href="#ch-tautologous-name-trap">The Tautologous Name Trap</a>
<a href="#ch-names-are-fickle">Names are Fickle</a>
<a href="#ch-abstracting-too-soon">Abstracting Too Soon</a>
<a href="#ch-speaking-the-native-tongue">Speaking the Native Tongue</a>
<a href="#ch-naming-and-teaching">Naming and Teaching</a>
<a href="#ch-authors-note" class="extended">Author’s Note</a>
</div>
</div>
<div class="bookmark">
</div>
<div class="grid-cover">
<div class="cover">
<h1>Naming Things</h1>
<h2>Thoughts on one of coding’s most elusive tasks.<br />By Ka Wai Cheung of <a href="https://www.donedone.com" target="_blank">DoneDone</a>.</h2>
<h4><a href="#" id="btn-cover-click">Start reading...</a></h4>
</div>
</div>
<div class="chapter" id="ch-introduction">
<div class="grid-content">
<div class="content">
<h2>Introduction</h2>
<p class="emphasis">
Here’s a little insight into what I think about when I write code.
</p>
<p>
I’m working on—what I’ll call for now—a <em>data migration</em> feature. It’s for the brand new version of <a href="https://www.donedone.com">DoneDone</a>, the task tracking and customer support app I’ve worked on for the past decade. Developing a product for this long, I’m intimately familiar with its code—like a scupltor chiseling away endlessly at a large piece of stone.
</p>
<p>
The goal of this migration feature is to give our customers an easy way to bring their existing data over from the old version of DoneDone (which we call <em>Classic</em>) to this new version. I wish I could tell you this is a simple mapping of database tables from Classic over to the new version, but it’s far from it. The new DoneDone is markedly different from its predecessor; Some data maps simply, other data requires some massaging, and some stuff simply can’t be mapped at all.
</p>
<p>
For the next week, I chisel away at this feature from top to bottom. I develop a screen to sign in to the old system, one to let users choose the projects they want to move over, and one to see the progress of their migration requests. On the backend, I work on a number of database updates to store these requests. I then write a separate service that picks up these requests to perform the arduous work of moving this data over “cleanly”. There are other tangential pieces I build along the way, like emailing the requester when the migration is complete and broadcasting error notifications.
</p>
<p>
It’s intense work. But after a week, I feel confident about this new feature.
</p>
<p>
Before I’m ready to release it, I give my code another onceover—like re-reading a manuscript from the beginning again with a fresh set of eyes. I tend to pick out things I don’t like about my code best this way.
</p>
<p>
The first thing I look at is naming. I try to use the same terms when I write code as when I <em>talk</em> about a feature. This avoids any unnecessary mental mapping when I transition between the screen and the rest of the world. So naturally, my codebase is littered with derivates of the word <em>migration</em>.
</p>
<ul>
<li>There’s a <code>ClassicMigrator</code> project in my codebase.</li>
<li>Methods named <code>QueueMigrationRequest()</code> and <code>MigrateClassicProjects()</code>.</li>
<li>Class properties like <code>EligibleForMigration</code> and <code>HasMigratableProjects</code>.</li>
<li>There are models, views, and controllers with every derivative of <em>Migrate</em> sprinkled around. The copy on the application uses the words <em>migrate</em> and <em>migration</em> too.
</li>
</ul>
<p>
On this re-read, the word is eating at me. Mike (my business partner) and I have been using the word “migration” in reference to this feature the whole time. It’s an important word to get right.
</p>
<p>
Sometimes you use a word so much that you no longer think about what it actually means; You just know what it’s <em>supposed</em> to mean. Here’s the problem: We aren’t actually migrating data.
</p>
<p>
Migrate has this connotation that something is leaving one place to go to another, like a flock of birds migrating south for the winter. In our case, data isn’t leaving the Classic version. That data is still there—untouched—after the migration. I wrote it this way so existing customers can try the new system using their existing data, but if they don’t like it, they can stick with Classic.
</p>
<p>
Migrate is misleading. Using that word in the application copy might make customers apprehensive about their existing data. Using that word in code might confuse future developers about what the feature actually does.
</p>
<p>
I contemplate replacing <em>migration</em> with <em>copy</em>. It’s clear that copying doesn’t mean removing the original. But, this isn’t quite right either. As I mentioned earlier, this data transfer isn’t a literal copy. There are some things that don’t translate perfectly, or at all. Copying also seems like a fast, mindless operation—a simple <span class="key">CTRL</span>+<span class="key">C</span> <span class="key">CTRL</span>+<span class="key">V</span> exercise. That’s not what this is.
</p>
<p>
I tell Mike about my conundrum.
</p>
<p>
After some thought, he suggests we use the word <em>import</em> instead. Ah ha!
</p>
<p>
There’s a heftiness to the word <em>import</em> that feels right. Whenever I think about importing data, I envision metallic gear icons and the momentary spiking of CPU graphs. Even when you import things in the real world, it has that same feeling of heft—huge cargo ships meandering across the ocean lugging thousands of tons of goods.
</p>
<p>
The word <em>import</em>, as it’s normally used in technical terms, also doesn’t feel like data is leaving one place and going to another. I think of importing data from a file I’ve uploaded. I know the data on the file doesn’t disappear. I also don’t necessarily expect a one-to-one mapping between my data and the imported data. Import seems like the perfect word to me.
</p>
<p>
So, I end up substituting <em>migrate</em>, and all its various derivatives, with <em>import</em>. I’m much happier with this change.
</p>
<hr />
<p>
I obsess over names. Finding that perfect name gives me the same kind of adrenaline boost I get after I’ve solved a difficult problem or figured out a much cleaner approach to an ugly solution.
</p>
<p>
My obsession with naming started from a quote I read some time ago. If you’ve written code long enough, there’s a good chance you’ve heard it as well.
</p>
<blockquote>
“There are only two hard things in Computer Science: cache invalidation and naming things.”
</blockquote>
<div class="quoter">
Phil Karlton
</div>
<p>
Karlton was a software architect at Netscape. There is suprisingly little other information I could find about him though I’m sure he’s done great work. But, it’s this quote that he will be forever remembered by in the programming industry.
</p>
<p>
The first time I read this quote, I remember chuckling to myself. First, because I can think of many things that are difficult for me in programming. Second, because naming wasn’t initially among those things; I had never thought about naming as a difficult exercise. Yet, we all have written and read names that confuse, misdirect, conflate, or otherwise mistify us.
</p>
<p>
So, how do you name things well? Unlike so many other things in programming, an incoherent name won’t be caught by the compiler. There are no metrics for naming. A bad name won’t break your code. A good name won’t speed up your build.
</p>
<p>
Naming is elusive. It has a lot to do with gut, feel, style and even aesthetics. It is, in my humble opinion, the most subjective of technical subjects.
</p>
<p>
Though there are no metrics for good names, it deserves as much attention as all the other skills we preach in programming—like good architecture, writing “clean code”, or rigid testing. While these other practices are critical, they share the common drawback that you cannot see these things instantly. It’s only after digesting the codebase and working with it for awhile that you reap its benefits.
</p>
<p>
On the other hand, a codebase with good names pays off <em>immediately</em>. They are the first things a programmer sees when reading new code. They make code more approachable. With modern tooling, you can also change the names of things safely and quickly.
</p>
<hr />
<p>
This book is about how focusing on names can drive us toward better code—regardless of the languages, tools, or development environment you use. Many of the examples in this book come directly from, or were inspired by, real code I’ve written for DoneDone over the past decade. <a href="#ch-imagining-objects">Let’s begin</a>.
</p>
</div>
</div>
</div>
<div class="chapter" id="ch-imagining-objects">
<div class="grid-content">
<div class="content">
<h2>Imagining Objects</h2>
<p class="emphasis">
I think the term <em>object-oriented programming</em> is misleading.
</p>
<p>
Textbooks tend to explain concepts like classes and interfaces by using dogs, cats, and other domesticated cuddly animals. But, these aren’t realistic examples for most coders. Most of the things we call “objects” in code don’t have a direct physical representation in the real world.
</p>
<p>
We should really call it noun-oriented programming. A noun can be a person, place, thing, or idea. Most classes really are <em>ideas with functionality</em>.
</p>
<p>
Classes sometimes manifest because we find ourselves with a set of functions and properties that have a common purpose that we want to wrap up in a neat little bundle. But, these classes don’t always have a physical translation. This is where wishy-washy names like <code>UserManager</code>, <code>MessagingHelper</code>, and <code>AppHandler</code> are born.
</p>
<p>
Working through a codebase littered with these kinds of class names reminds me of working in a bloated organization where everybody is some form of middle-management. When should I direct a question to the <em>Regional Vice President</em> versus the <em>District Assistant Principal</em>?
</p>
<p>
When I read code like this, I have to dig into these classes to figure out what purpose they serve. When I know there’s some functionality out there I want to leverage, I have a harder time remembering where it lives. <em>Was it in that helper doohickey or in the other manager thingamajig?</em>
</p>
<p>
There are ways around this. Generic names might be a sign that the guts of the class belong elsewhere. For instance, maybe the methods inside that <code>UserManager</code> class can be moved into the <code>User</code> class itself. It might also be a sign that the class does too many things and needs to be split up into smaller pieces. Perhaps there are natural groupings inside that <code>AppHandler</code> class—one that handles initialization, one that handles routing, one that deals with exception handling, and so forth. More specific names can be derived from there.
</p>
<p>
If it’s neither of those cases, sometimes I just have to face reality: A class can be hard to name because it does something that doesn’t easily translate in the real world. That’s when a little imagination helps. Even when a class is responsible for something that only makes sense in my code, there’s usually some metaphorical noun out there I can apply to it to make it memorable. This makes it easier to recall when I need to revisit that “object” again.
</p>
<hr />
<p>
The other day, I was looking at code I wrote awhile back that allows DoneDone users to reset their password. The reset password function works like most other apps:
</p>
<ul>
<li>A user enters their email address in a “Forgot Password” form from the app.</li>
<li>They receive an email with a link containing an encrypted token embedded in the querystring.</li>
<li>When clicked, the request passes the token to the server and is decrypted.</li>
<li>The information from the decryption determines whether the reset link is still valid and which user originally requested the reset.</li>
</ul>
<p>
On this re-read, I don’t like how the token concept is implemented. Bits of logic are sprinkled in too many places. The token is encrypted on one layer of the stack and decrypted on a completely different layer. There are also a couple of places where I write repeated code to check whether the token is still valid.
</p>
<p>
But, what makes me most hungry to clean this code up is that the concept is <em>nearly identical</em> to the process a user takes to complete their initial registration.
</p>
<p>
It’s clear that a better approach is to wrap up this token into a single object. Let the object handle all of it—the encryption, decryption, and validation of the token. Then, I can re-use it for both password resets and user registrations.
</p>
<p>
I get to a place I’m quite happy with. The guts of the object look something like this.
</p>
</div>
</div>
<div class="grid-left-code">
<div class="code-block">
<pre>
public sealed class <span class="blanked">AuthToken</span>
{
private readonly DateTime _utc_date_issued;
public readonly int UserID;
public readonly string EmailAddress;
public readonly string EncryptedToken;
<span class="1-d1">public AuthToken(int user_id, string email)
{
UserID = user_id;
EmailAddress = email.ToLower().Trim();
_utc_date_issued = DateTime.UtcNow;
EncryptedToken = // Omitted for simplicity...
}</span>
<span class="1-d2">public AuthToken(string encrypted_token)
{
try
{
EncryptedToken = encrypted_token;
UserID = // Deduced from the token...
EmailAddress = // Deduced from the token...
_utc_date_issued = // Deduced from the token...
}
catch
{
throw new InvalidInput("Cannot decrypt token!");
}
}</span>
<span class="1-d3">public bool IssuedWithinMinutes(int minutes)
{
return (_utc_date_issued.AddMinutes(minutes) > DateTime.UtcNow);
}</span>
}</pre>
</div>
<div class="content">
<p>
Taking a quick walkthrough of this object, you’ll notice that there are two constructors.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="1-d1">One hydrates the properties of the object with a <code>user_id</code> and <code>email</code> of the user when a password reset (or registration completion request) is initiated</a>. The timestamp of the token is set to the moment the instance is created. It also wraps all of this data together into an encrypted token.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="1-d2">The other hydrates the same object with the encrypted token. The token is decrypted and the other properties are deduced from the decryption</a>. This is called during the request when a user clicks the link they received from the email.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="1-d3">The <code>IssuedWithinMinutes</code> public method allows code elsewhere to decide whether to honor the request</a>. For instance, a password reset link might be valid for only ten minutes whereas a user registration link could be valid for a few hours.
</p>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
I’m giddy with the promises of such an object. I’m able to clean up some duplicate logic used by both the password reset and user registration processes. Whereas the encryption and decryption process once lived in random helper methods on different layers of the stack, they now have a comfortable home.
</p>
<p>
The last hurdle, however, is a big one. What do I name this thing? This “object” is not a dog or cat. I don’t really know what this thing is.
</p>
<p>
My initial attempt, <code>AuthToken</code> was half-hearted. I just wanted to get something down so I could finish the implementation. Reading this name again brings up all sorts of questions and lackluster answers.
</p>
<ul>
<li>
<strong>Does “Auth” mean “Authorization” or “Authentication”?</strong> In this case, it kind of means <em>both</em>. That doesn’t really help.
</li>
<li>
<strong>Does this object represent the encrypted token?</strong> Kind of. It really represents the encrypted token <em>in addition to</em> the data the token represents. Calling it <code>AuthToken</code> while also having a property with the name <code>EncryptedToken</code> is confusing. It’s more than just the token. It’s easy to get into the trap of naming an object for only part of its reason for being.
</li>
<li>
<strong>What is this object supposed to be used for?</strong> In the lexicon of object naming, <code>AuthToken</code> is about as generic as <code>UserManager</code>.
</li>
</ul>
<p>
This clearly isn’t the right name. But, what comparable thing possibly exists in the real world like this?
</p>
<p>
I begin to think about something that an <em>authority</em> creates for someone, who can later exchange this thing to do whatever the authority said they could do.
</p>
<p>
A <em>ticket</em> comes to mind. But, that conjures up thoughts of going to a sporting event or movie premiere, as if there’s a specific time and place to redeem it. It also makes me think of a parking ticket. Password resets and user registrations are neither particularly exciting nor dreadful. The metaphor doesn’t feel quite right.
</p>
<p>
A <em>permit</em>? A permit is valid for a set period of time and it lets someone do something agreed to by an authority until it expires. Plus, a permit is something given to you usually by a governing body, not your local movie theater or sporting venue. This feels spot on.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="1-d4">I end up changing the class name to <code>PermitForUserUpdate</code></a>. The implementation instantly feels more readable. For instance, <a href="#" class="code-ref" data-code-ref="1-d5">the method <code>IssuedWithinMinutes()</code> reads more naturally</a> when used in context. Permits in the real world are normally <em>issued</em>. Here’s how I can validate a password reset permit hasn’t expired yet.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
var permit = new <span class="1-d4">PermitForUserUpdate</span>(encrypted_token);
if (!<span class="1-d5">permit.IssuedWithinMinutes(10)</span>)
{
throw new Exception("This permit is expired!");
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<hr />
<p>
When opportunities like these present themselves in your code, stop for a minute and see if you can find a replacement for that really vague class name. Renaming classes might require a little bit of imagination, but done repeatedely, your objects become more memorable and your codebase starts to read more fluidly.
</p>
</div>
</div>
</div>
<div class="chapter" id="ch-name-hunting">
<div class="grid-content">
<div class="content">
<h2>Name Hunting</h2>
<p class="emphasis">
There never seems to be time to clean up code.
</p>
<p>
No client wants to pay for it. No product manager wants to see energy spent with no feature improvements. You sometimes have to clean up surreptitiously as you go. Do it behind their backs.
</p>
<blockquote class="smaller">
“Of course, many [managers] say they are driven by quality but are more driven by schedule...In these cases I give my more controversial advice: Don’t tell! Subversive? I don’t think so.”
</blockquote>
<div class="quoter">
Martin Fowler, <a href="https://martinfowler.com/books/refactoring.html">Refactoring: Improving the Design of Existing Code</a>
</div>
<p>
The good news is, you don’t need a long stretch of dedicated time to make positive impacts on your code. You can get a lot done in small spurts. One of my favorite exercises is one of the simplest: <em>Find things to name</em>. I look for bits of overexposed logic, then replace the logic with a method or property that I can define with a meaningful name. Done repeatedly, it can quickly make souring code sweet.
</p>
<hr />
<p>
On the new DoneDone, we’re using <a href="https://vuejs.org/">Vue.js</a> to deliver most of our front-end. I notice a conditional on a Vue element that looks like this:
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
<div <span class="2-d1">v-if="![’xs’, ’sm’, ’md’].includes($mq)"</span>>
...
</div></pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
If you’re unfamiliar with Vue syntax, no big deal. The <a href="#" class="code-ref" data-code-ref="2-d1"><code>v-if</code> attribute</a> works just like a normal <code>if</code> statement, with a Typescript expression inside of it. Inside an HTML element, it determines if that element should be rendered at all. In this case, I have a <code><div></code> that I only want to show if the statement <code>![’xs’, ’sm’, ’md’].includes($mq)</code> is true.
</p>
<p>
But, what does this code <em>actually</em> mean? Well, it evaluates to <code>true</code> if the “extra small”, “small”, or “medium” media query breakpoints are <em>not</em> hit based on the size of the browser. Put more meaningfully, it tells us if <em>the current browser width is sized to at least the width of a normal desktop screen</em>.
</p>
<p>
When I scan this statement, it looks cryptic. Out of place. Too specific in the context of the code around it.
</p>
<p>
I can quickly fix this line by swapping the logic with a well-named property, like <a href="#" class="code-ref" data-code-ref="2-d2"><code>isDesktopWidth</code></a>.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
<span class="2-d2">isDesktopWidth()</span>: boolean {
return ![’xs’, ’sm’, ’md’].includes(this.$mq)
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
Now, I get the satisfaction of cleaning up my original code up with something much more approachable.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
<div v-if="isDesktopWidth">
...
</div></pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
Not only does this read better, but I have a property I can reuse again in other parts of the application.
</p>
<hr />
<p>
You can spot an opportunity like this from a mile away—an overly technical bit of code lying around without a proper home. I usually write code like this on the first pass, when I’m just trying to get a feature to work right and I don’t care about where all the pieces fit. But, if I never make that second pass, then things quickly turn ugly.
</p>
<p>
In my earlier days, it would be easy to forget to do that second pass because I got lost in the relief of simply getting code to work right—or I was already past the deadline I had set for myself to do so.
</p>
<p>
I don’t skip that second pass anymore. It’s this pass where I focus heavily on naming. Where I look to say <em>what</em> rather than <em>how</em>. Where the readability of my code improves dramatically. It’s as critical a step as the first.
</p>
<p>
Take a moment to look at your own code—regardless of where you are in your stack. You might be surprised how many bits of messy logic are sprinkled about that you could wrap up into a meaningful name.
</p>
<h3>Empowering your objects</h3>
<p>
Logic bits don’t always have to look overly <em>technical</em> to benefit from replacing it with a named method or property.
</p>
<p>
Even in a case where I might see business logic already using the well-named properties of an object, there’s usually a way I can name that piece of logic and push it <em>back</em> into the class definition. Here’s an example.
</p>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
I have a <code>Person</code> class that houses some basic information used throughout my codebase.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public class Person
{
public string FirstName;
public string LastName;
public DateTime LastAccessTimestamp;
public AccountRole Role;
...
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
Instances of <code>Person</code> naturally spring up all over the place.
</p>
</div>
</div>
<div class="grid-left-code">
<div class="content">
<p>
For example, on a person’s profile screen, <a href="#" class="code-ref" data-code-ref="2-d3">I have an instance of <code>Person</code> named <code>authedPerson</code></a> used to display an user’s full name and a few links to other sections of the application, but only if they are an admin or owner in the account.
</p>
</div>
<div class="code-block">
<pre>
<div>
<h2><span class="2-d3">@authedPerson.FirstName @authedPerson.LastName</span></h2>
@if (<span class="2-d3">authedPerson.Role == AccountRole.ADMIN ||
authedPerson.Role == AccountRole.OWNER</span>)
{
<a href="...">Edit</a> | <a href="...">Cancel</a>
}
</div></pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
In another part of the application, <a href="#" class="code-ref" data-code-ref="2-d4">I use a person’s first name and last initial</a> to prep notification messages when they update a task.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
var subject = <span class="2-d4">person.FirstName + " " + person.LastName.Substring(0,1) + ".</span> updated the task.";</pre>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
I also have a method inside of a security class that checks <a href="#" class="code-ref" data-code-ref="2-d5">if a person has accessed the application within an hour</a>. If not, I require them to log in again.
</p>
</div>
<div class="code-block">
<pre>
if ((<span class="2-d5">person.LastAccessTimestamp - DateTime.UtcNow).TotalMinutes > 60</span>)
{
// Log out and send to the login screen.
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
There are a handful of other occurences like the examples above, where little bits of business logic against a <code>Person</code>’s properties are sprinkled about. Most of these bits feel so inconsequentually minor—simple, one-line constructions and statements—you might not even consider them to be “business logic” at all.
</p>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
For instance, in the profile screen example, displaying a person’s first and last name might not seem like <em>logic</em>, but it is—it represents a person’s <a href="#" class="code-ref" data-code-ref="2-d6">full name</a>. I can push this bit of logic back to the <code>Person</code> class itself and name it something meaningful.
</p>
</div>
<div class="code-block">
<pre>
public string <span class="2-d6">FullName</span>
{
get
{
return FirstName + " " + LastName;
}
}</pre>
</div>
</div>
<div class="grid-left-code">
<div class="content">
<p>
The same can be done for the special format of the person’s name in the subject line of the notification message. I could call this an <a href="#" class="code-ref" data-code-ref="2-d7">abbreviated name</a>.
</p>
</div>
<div class="code-block">
<pre>
public string <span class="2-d7">AbbreviatedName</span>
{
get
{
return FirstName + " " + LastName.Substring(0,1) + ".";
}
}</pre>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
Back on the profile screen, I can move the check for whether a person is an admin or owner as a property of the <code>Person</code> instead. In this case, the check determines whether this person has administrative access. <a href="#" class="code-ref" data-code-ref="2-d8"><code>HasAdminAccess</code> is a sound name</a> for this new property.
</p>
</div>
<div class="code-block">
<pre>
public bool <span class="2-d8">HasAdminAccess</span>
{
get
{
return Role == AccountRoleType.ADMIN || Role == AccountRoleType.OWNER;
}
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
The application access logic against the <code>Person</code> object within the security class can be pushed back to the class in a couple of ways. Here’s that conditional statement again.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
if ((person.LastAccessTimestamp - DateTime.Now).TotalMinutes > 60)...
</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
There are a few ways I could go about moving this. The entire statement is asking if the person has been idle for more than 60 minutes, so I could take this entire statement and turn it into <a href="#" class="code-ref" data-code-ref="2-d9">a boolean property off <code>Person</code> like so</a>:
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public bool <span class="2-d9">HasPersonBeenIdleForMoreThan60Minutes</span>
{
get
{
return (person.LastLoggedIn - DateTime.Now).TotalMinutes > 60;
}
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
This cleans up <em>all</em> of the logic from the security method. But, the name feels way too specific. If someone were just inspecting the <code>Person</code> class, they might ask why such a specific property exists. In addition, if I change the requirements around the idle time, I might easily forget to change the name of the property.
</p>
<p>
I don’t like these tradeoffs. In this case, I’d rather pull back on the specificity of the property so it has a better chance of being reused and maintained well over time.
</p>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
For instance, I could push <em>just</em> the calculation of the idle minutes into the object and call this property <code>MinutesIdle</code>.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public int MinutesIdle
{
get
{
return (person.LastAccessTimestamp - DateTime.Now).TotalMinutes;
}
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
Or, I could convert the logic to a method and let the caller <a href="#" class="code-ref" data-code-ref="2-d9-1">pass in the idle minutes</a> to compare.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public bool IdleLongerThanMinutes(<span class="2-d9-1">int minutes</span>)
{
return (person.LastAccessTimestamp - DateTime.Now).TotalMinutes > minutes;
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
These two examples are both decent options. But, I like the first option—it feels more straightforward and reads more coherently.
</p>
<p>
With these updates, the <code>Person</code> class now develops into something a lot more powerful. Here’s what the full class now looks like with these additional, well-named properties.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public class Person
{
public string FirstName;
public string LastName;
public DateTime LastLoggedIn;
public AccountRoleType Role;
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
public string AbbreviatedName
{
get
{
return FirstName + " " + LastName.Substring(0,1) + ".";
}
}
public bool HasAdminAccess
{
get
{
return Role == AccountRoleType.ADMIN ||
Role == AccountRoleType.OWNER;
}
}
public int MinutesIdle
{
get
{
return (person.LastAccessTimestamp - DateTime.Now).TotalMinutes;
}
}
...
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
By moving this logic into the <code>Person</code> class, it’s now easier to DRY up my codebase. There will likely be other places that require displaying a person’s full name or knowing whether they have administrative privileges. Those answers are already baked into the object itself.
</p>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
Besides reuse, the biggest gain comes from the improved readability of my code. Here’s how the improved implementations look like. In my HTML markup, the business logic visually competes far less with the HTML around it.
</p>
</div>
<div class="code-block">
<pre>
<div>
<h2>@authedPerson.FullName</h2>
@if (authedPerson.HasAdminAccess)
{
<a href="...">Edit</a> | <a href="...">Cancel</a>
}
</div></pre>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
The subject of the email notification can also be interpreted with one glance. You don’t spend time focusing on the details of how the person’s name is being displayed anymore.
</p>
</div>
<div class="code-block">
<pre>
var subject = person.AbbreviatedName + " updated the task.";</pre>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
Finally, the conditional check on the person’s login date can be understood instantly, instead of having to parse (even if for a brief moment) through the date math.
</p>
</div>
<div class="code-block">
<pre>
if (person.MinutesIdle > 60)
{
// Log out and send to the login screen.
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
The best part of this work is that, once you get accustomed to the game, it’s not a heavy effort. It actually becomes a bit addictive. You can make these simple refactorings quickly and stop whenever the time you’ve devoted is up (or your manager comes back from lunch).
</p>
<hr />
<p>
Keep hunting for places where you can corral bits of logic into meaningful names, whether as standalone properties or back into the objects they derived from. It will do wonders for the clarity of your code.
</p>
</div>
</div>
</div>
<div class="chapter" id="ch-breaking-methods-apart">
<div class="grid-content">
<div class="content">
<h2>Breaking Methods Apart</h2>
<p class="emphasis">
As you add more parameters to a method, two problems tend to occur.
</p>
<p>
First, the method starts doing too much. There might be tricky conditional logic that would be better separated into their own methods. Second, the name of the method becomes increasingly more vague or more misleading. Whenever I’ve augmented a method to support a new feature, I revisit it to see if breaking it apart can help alleviate both problems—even if the updates seem miniscule.
<hr />
<p>
For years, DoneDone has only allowed customers the option to cancel an account immediately—it was instantaneous and irreversible.
</p>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
I have a method off of a billing repository class that’s responsible for invoking the cancellation when requested. The guts of the method are involved, but <a href="#" class="code-ref" data-code-ref="4-d1">the method signature</a> is about as simple a read as you can imagine.
</p>
</div>
<div class="code-block">
<pre>
public class BillingRepository
{
<span class="4-d1">public void CancelAccount(int account_id)</span> { ... };
...
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
Over the years, we’ve had customers who’ve wanted to cancel their account at the end of their term which could be several months out. Rather than remembering to cancel their account in a few months, they wanted the account to automatically cancel on the last day of their term.
</p>
<p>
I start implementing this by tacking on a parameter to <code>CancelAccount()</code>. Since there are now two cancellation options, cancelling immediately <em>or</em> at the end of their current billing period, I choose the simplest parameter type that fills the need, the trusty boolean.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="4-d11">I decide to name it <code>cancel_at_period_end</code></a>. Now, I can pass in <code>true</code> to handle this new special case, and <code>false</code> to handle the original case.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public void CancelAccount(int account_id, <span class="4-d11">bool cancel_at_period_end</span>);
</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
After I’ve implemented the new code to handle the update, I then update <a href="#" class="code-ref" data-code-ref="4-d12">all existing references</a> to this method that handle the immediate cancellations.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
_billing.CancelAccount(account_id, <span class="4-d12">false</span>);
</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
But something doesn’t feel right about this method signature.
</p>
<p>
At a glance, it’s hard to tell what the <code>false</code> parameter means. Having just written the updates, it makes sense to me now. But it might not to someone else (or to myself in a few days). They’ll have to look at the method signature and perhaps even drill into the method to be sure.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="4-d2">I add a comment above each call to <code>CancelAccount()</code></a> for clarity. It also helps differentiate between the new code I’ll be adding later to handle the new option of canceling at the end of the period.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
<span class="4-d2">// Cancel the account immediately...</span>
_billing.CancelAccount(account_id, false);</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
<em>Better</em>. But comments never age well. The method call still feels strange. The standard cancellation case (canceling immediately) accepts the <code>false</code> parameter. Passing in <code>false</code> as the base case just feels odd—it’s as if I have to suppress something to perform the <em>default</em> action.
</p>
<p>
I can get around this pretty quickly though. Since I’m working with a boolean parameter, I can change its meaning so that the standard case passes in <code>true</code> and update my code accordingly.
</p>
</div>
</div>
<div class="grid-right-code">
<div class="content">
<p>
<a href="#" class="code-ref" data-code-ref="4-d3">I swap the <code>cancel_at_period_end</code> parameter with <code>cancel_now</code></a> and <a href="#" class="code-ref" data-code-ref="4-d4">modify the implementation</a>.
Now, the default case passes in <code>true</code>.
</p>
</div>
<div class="code-block">
<pre>
public void CancelAccount(int account_id, <span class="4-d3">bool cancel_now</span>) { ... }
...
// Cancel the account immediately...
_billing.CancelAccount(account_id, <span class="4-d4">true</span>);</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
But, I’ve introduced a more onerous problem. By simply reading the <code>CancelAccount()</code> method signature, I can’t quite tell what passing in <code>false</code> would do. Would it cancel in a day? In a month? At the end of the period?
</p>
<p>
At this point, I’ve exhausted my options with the boolean parameter. While it allows for both options, the options aren’t clear from the method signature.
</p>
<p>
I often find this is the case with booleans when the concept it describes has two cases but the options aren’t really <em>opposites</em>. That’s the case here—the natural opposite of <code>cancel_now</code> isn’t <code>cancel_at_period_end</code> in the way the natural opposite of <code>open</code> is <code>closed</code>.
</p>
<p>
<a href="#" class="code-ref" data-code-ref="4-d5">I could try introducing an enumerated value instead</a>.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
<span class="4-d5">enum CancelType
{
NOW,
AT_PERIOD_END
}</span>
...
public void CancelAccount(int account_id, <span class="4-d5">CancelType cancel_type</span>);
...
_billing.CancelAccount(account_id, <span class="4-d5">CancelType.NOW</span>);</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
This is an improvement. On the plus side, I’ve gotten rid of the ambiguity issues I had with the boolean parameter. It also leaves me better positioned to introduce additional cancelation types in the future.
</p>
<p>
However, this just doesn’t feel like one of those features we’d continually augment in the near future. There just aren’t that many variations of canceling DoneDone that would make sense. And, now I’ve introduced a new type as well as a new parameter.
</p>
<p>
I ultimately decide to simplify things. I create two distinct cancelation methods and convey the type of cancelation in the <a href="#" class="code-ref" data-code-ref="4-d51">method names</a>.
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public void <span class="4-d51">CancelAccountNow</span>(int account_id);
public void <span class="4-d51">CancelAccountAtPeriodEnd</span>(int account_id);</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
With this update, the standard and unique cancelation implementations both read clearly. There’s zero ambiguity in either what the method does or what the parameters mean.
</p>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
I also get an additional benefit. Breaking the method out into two methods allows me to separate the implementations of each. In the original approach, I’d have to do something like this.
</p>
</div>
</div>
<div class="grid-left-code">
<div class="content">
<p>
The method body would not only be much longer, but it would have more than one responsibility. Breaking the methods apart not only clarify their use, but will make finding and updating their implementations easier down the road.
</p>
</div>
<div class="code-block">
<pre>
void CancelAccount(int account_id, bool cancel_at_period_end)
{
if (cancel_at_period_end)
{
// Implementation for canceling at period end
}
else
{
// Implementation for canceling immediately
}
}
</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<hr />
<p>
I find a similar opportunity arises when <code>null</code> values are passed to a method. I can usually a new method to handle the <code>null</code> case with a much clearer name.
</p>
<p>
In DoneDone, I have a series of “bulk edit” methods that live in a services layer. Each accepts a list of <code>task_ids</code> and performs some action on the task they represent. One of these is a function to bulk update the tasks’ due dates.
</p>
<p>
Here’s the abbreviated signature. (Due dates are optional—hence the nullable <code>DateTime?</code> object representing the due date in the parameter list.)
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
public void UpdateDueDates(List<long> task_ids, DateTime? due_date, ...);</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
Crawling up to the application layer, here’s where <a href="#" class="code-ref" data-code-ref="4-d6">I call the bulk edit due date method</a> based on the user’s input:
</p>
</div>
</div>
<div class="grid-code-only">
<div class="code-block">
<pre>
switch (input.ActionChangeType)
{
case BulkActions.UPDATE_DUE_DATE:
<span class="4-d6">_service.UpdateDueDates(input.TaskIDs, DateTime.Parse(input.Value),...);</span>
break;
...
}</pre>
</div>
</div>
<div class="grid-content">
<div class="content">
<p>
In a recent feature update, we wanted to explicitly add an option to <em>remove</em> due dates from all tasks. Because the <code>UpdateDueDates()</code> method already gives the option to pass in a <code>null</code> value, <a href="#" class="code-ref" data-code-ref="4-d7">the update is straightforward</a>:
</p>