Vaidas Pilkauskas - Comprehensible code
-
Upload
agile-lietuva -
Category
Education
-
view
78 -
download
5
Transcript of Vaidas Pilkauskas - Comprehensible code
![Page 1: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/1.jpg)
This space intentionally left blank
![Page 2: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/2.jpg)
COMPREHENSIBLE CODECOMPREHENSIBLE CODE2017, Vaidas Pilkauskas
@liucijus2017, Vaidas Pilkauskas
@liucijus
![Page 3: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/3.jpg)
GREEN
![Page 4: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/4.jpg)
YELLOW
![Page 5: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/5.jpg)
BLUE
![Page 6: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/6.jpg)
PINK
![Page 7: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/7.jpg)
PINK YELLOWGREENBLUE
REDBLACK GREY
BROWN
![Page 8: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/8.jpg)
COMPREHENSIBLE CODECOMPREHENSIBLE CODE2017, Vaidas Pilkauskas2017, Vaidas Pilkauskas
![Page 9: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/9.jpg)
![Page 10: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/10.jpg)
@liucijus
![Page 11: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/11.jpg)
/** * User: Vaidas_pilkauskas * Date: 17/11/10 * Time: 15:12 */
![Page 12: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/12.jpg)
…, programs must be written for people to read, and only incidentally for
machines to execute
—SICP
![Page 13: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/13.jpg)
WHO READSTHE CODE?
WHO READSTHE CODE?
mrhayata | Flickr
![Page 14: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/14.jpg)
YOU
![Page 15: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/15.jpg)
THE FUTURE YOU
![Page 16: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/16.jpg)
USERS
![Page 17: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/17.jpg)
CONTRIBUTORS
![Page 18: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/18.jpg)
FUTURE MAINTAINERS
![Page 19: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/19.jpg)
READABLE CODEOptimized for reading
Cleanly editedExplicitly structured
![Page 20: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/20.jpg)
https://wallpaperscraft.com/download/cat_window_broken_peep_104131/1920x1080
![Page 21: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/21.jpg)
Lennart van Uffelen
![Page 22: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/22.jpg)
![Page 23: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/23.jpg)
![Page 24: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/24.jpg)
COMPREHENSION
![Page 25: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/25.jpg)
![Page 26: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/26.jpg)
LONG LINES
![Page 27: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/27.jpg)
![Page 28: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/28.jpg)
![Page 29: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/29.jpg)
![Page 30: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/30.jpg)
![Page 31: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/31.jpg)
![Page 32: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/32.jpg)
![Page 33: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/33.jpg)
![Page 34: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/34.jpg)
HOW LONG?
Readable is less than 80, but:
→ Intellij IDEA has default marker at 120
Many tools work with 120
![Page 35: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/35.jpg)
EXAMPLES OF VISUAL NOISE
INCONSISTENCY
UNCONVENTIONAL STYLE
TOOL WARNINGS
EXCESSIVE EMPTY LINES
UNUSED IMPORTS
UNFORMATTED CODE
![Page 36: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/36.jpg)
![Page 37: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/37.jpg)
![Page 38: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/38.jpg)
IGNORING WARNINGS
![Page 39: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/39.jpg)
IGNORING WARNINGS
Puts Broken Window into effect
![Page 40: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/40.jpg)
IGNORING WARNINGS
False warnings hide important ones
![Page 41: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/41.jpg)
IGNORING WARNINGS
Distractions (context switch)Inbox Zero problem
![Page 42: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/42.jpg)
DEALING WITH WARNINGSFix the code—the best option
Disable/configure warnings to fit the code
Ask vendor to provide good defaults
![Page 43: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/43.jpg)
![Page 44: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/44.jpg)
![Page 45: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/45.jpg)
ILLOGICAL CODE STRUCTURE
![Page 46: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/46.jpg)
LOGICAL STRUCTURE
Group of elements which are in the same level of abstraction
![Page 47: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/47.jpg)
aspects.setAspect(Web(request.url, request.remoteIp, request.remotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent), request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName))
![Page 48: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/48.jpg)
aspects.setAspect(Web(request.url, request.remoteIp, request.remotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent), request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName))
![Page 49: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/49.jpg)
aspects.setAspect(Web(request.url, request.remoteIp, request.remotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent), request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName))
![Page 50: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/50.jpg)
aspects.setAspect(Web(request.url, request.remoteIp, request.getRemotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent, request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName))
![Page 51: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/51.jpg)
aspects.setAspect(Web(request.url, request.remoteIp, request.getRemotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent, request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName))
![Page 52: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/52.jpg)
aspects.setAspect(Web(request.url, request.remoteIp, request.remotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent), request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName))
![Page 53: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/53.jpg)
![Page 54: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/54.jpg)
aspects.setAspect( Web( request.url, request.remoteIp, request.remotePort, request.localIp, request.localUrl, UserAgent.from(request.userAgent), request.cookieDomain, request.appUrl, Id(request.requestId), request.dateTime, request.isRpcRequest, WebGeo(request.geo), request.getServerName ))
![Page 55: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/55.jpg)
aspects.setAspect( Web( url = request.url, remoteIp = request.remoteIp, remotePort = request.remotePort, localIp = request.localIp, localUrl = request.localUrl, userAgent = UserAgent.from(request.userAgent), cookieDomain = request.cookieDomain, appUrl = request.appUrl, id = Id(request.requestId), timestamp = request.dateTime, isRpcRequest = request.isRpcRequest, geo = WebGeo(request.geo), serverName = request.getServerName ))
![Page 56: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/56.jpg)
val webAspect = Web( url = request.url, remoteIp = request.remoteIp, remotePort = request.remotePort, localIp = request.localIp, localUrl = request.localUrl, userAgent = UserAgent.from(request.userAgent), cookieDomain = request.cookieDomain, appUrl = request.appUrl, id = Id(request.requestId), timestamp = request.dateTime, isRpcRequest = request.isRpcRequest, geo = WebGeo(request.geo), serverName = request.getServerName)
aspects.setAspect(webAspect)
![Page 57: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/57.jpg)
val client = Client( name = ..., addresses = Seq( Address( type = Work, building = Building( room = Room(301), street = Street(“Rūdninkų”), city = City(“Vilnius”), zip = Zip(“123123”), ) ) ))
![Page 58: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/58.jpg)
ARGH! BRACES!!1
{ “foo”: “bar”}
<foo> <bar /></foo>
Foo( “bar”)
{ “foo”: “bar”}
<foo> <bar /></foo>
Foo( “bar”)
![Page 59: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/59.jpg)
Tools and Formatting
![Page 60: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/60.jpg)
val message = ContactActivityMessage(builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))
![Page 61: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/61.jpg)
val message = ContactActivity(builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))
![Page 62: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/62.jpg)
val message = ContactActivity( builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))
![Page 63: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/63.jpg)
val message = ContactActivityMessage( builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))
![Page 64: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/64.jpg)
Examples
![Page 65: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/65.jpg)
val asSiteContact = contact.details.asSiteContact(count) .copy(lastActivity = updated)
// BAD: Chain logic group split
![Page 66: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/66.jpg)
val asSiteContact = contact.details.asSiteContact(count).copy(lastActivity = updated)
// GOOD: Chaining on the same line
![Page 67: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/67.jpg)
val asSiteContact = contact .details .asSiteContact(count) .copy(lastActivity = updated)
// GOOD: Chain member per line
![Page 68: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/68.jpg)
enum State { READ, WRITE, PAUSE, STOP}
// BAD: Broken logical group
![Page 69: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/69.jpg)
enum State { READ, WRITE, PAUSE, STOP}
// WORSE: Looks clean, but has broken logical group
![Page 70: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/70.jpg)
enum State { READ, WRITE, PAUSE, STOP}
enum State { READ, WRITE, PAUSE, STOP}
// GOOD
![Page 71: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/71.jpg)
val foo = Foo(Bar(baz = Varoom( prop1 = "val", prop2 = "val2", prop3 = "val3), faz = Seq("one", "two")))
operations.query(contactById, Map( "site_id" -> getBytes(siteId), "contact_id" -> getBytes(contactId)), ContactMapper)
// BAD: hard to spot relations
![Page 72: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/72.jpg)
val foo = Foo( Bar( baz = Varoom(prop1 = "val", prop2 = "val2", prop3 = "val3), faz = Seq("one", "two") ))
operations.query( contactById, Map( "site_id" -> getBytes(siteId), "contact_id" -> getBytes(contactId) ), ContactMapper)
// GOOD: explicit relations
![Page 73: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/73.jpg)
case class Activity(contact: Contact, created: Instant, payload: String)
// BAD: fields in the same logical group given uneven placement
![Page 74: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/74.jpg)
case class Activity(contact: Contact, created: Instant, payload: String)
case class Activity( contact: Contact, created: Instant, payload: String)
case class Activity( contact: Contact, created: Instant, payload: String)
// GOOD: all fields are equally significant
![Page 75: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/75.jpg)
CAN STRUCTURE BE AUTOMATED?
Concentrate on communicating intent,but Automate repetitive work
![Page 76: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/76.jpg)
There are other ways to communicate
![Page 77: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/77.jpg)
![Page 78: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/78.jpg)
CODE COMPREHENSIONis based on
NAMED ABSTRACTIONS and CODE STRUCTURE
![Page 79: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/79.jpg)
THANK YOU!
![Page 80: Vaidas Pilkauskas - Comprehensible code](https://reader031.fdocuments.us/reader031/viewer/2022022415/5a674d727f8b9a453d8b5b53/html5/thumbnails/80.jpg)
QUESTIONS?