80
This space intentionally left blank

Vaidas Pilkauskas - Comprehensible code

Embed Size (px)

Citation preview

Page 1: Vaidas Pilkauskas - Comprehensible code

This space intentionally left blank

Page 2: Vaidas Pilkauskas - Comprehensible code

COMPREHENSIBLE CODECOMPREHENSIBLE CODE2017, Vaidas Pilkauskas

@liucijus2017, Vaidas Pilkauskas

@liucijus

Page 3: Vaidas Pilkauskas - Comprehensible code

GREEN

Page 4: Vaidas Pilkauskas - Comprehensible code

YELLOW

Page 5: Vaidas Pilkauskas - Comprehensible code

BLUE

Page 6: Vaidas Pilkauskas - Comprehensible code

PINK

Page 7: Vaidas Pilkauskas - Comprehensible code

PINK YELLOWGREENBLUE

REDBLACK GREY

BROWN

Page 8: Vaidas Pilkauskas - Comprehensible code

COMPREHENSIBLE CODECOMPREHENSIBLE CODE2017, Vaidas Pilkauskas2017, Vaidas Pilkauskas

Page 9: Vaidas Pilkauskas - Comprehensible code
Page 10: Vaidas Pilkauskas - Comprehensible code

@liucijus

Page 11: Vaidas Pilkauskas - Comprehensible code

/** * User: Vaidas_pilkauskas * Date: 17/11/10 * Time: 15:12 */

Page 12: Vaidas Pilkauskas - Comprehensible code

…, programs must be written for people to read, and only incidentally for

machines to execute

—SICP

Page 13: Vaidas Pilkauskas - Comprehensible code

WHO READSTHE CODE?

WHO READSTHE CODE?

mrhayata | Flickr

Page 14: Vaidas Pilkauskas - Comprehensible code

YOU

Page 15: Vaidas Pilkauskas - Comprehensible code

THE FUTURE YOU

Page 16: Vaidas Pilkauskas - Comprehensible code

USERS

Page 17: Vaidas Pilkauskas - Comprehensible code

CONTRIBUTORS

Page 18: Vaidas Pilkauskas - Comprehensible code

FUTURE MAINTAINERS

Page 19: Vaidas Pilkauskas - Comprehensible code

READABLE CODEOptimized for reading

Cleanly editedExplicitly structured

Page 20: Vaidas Pilkauskas - Comprehensible code

https://wallpaperscraft.com/download/cat_window_broken_peep_104131/1920x1080

Page 21: Vaidas Pilkauskas - Comprehensible code

Lennart van Uffelen

Page 22: Vaidas Pilkauskas - Comprehensible code
Page 23: Vaidas Pilkauskas - Comprehensible code
Page 24: Vaidas Pilkauskas - Comprehensible code

COMPREHENSION

Page 25: Vaidas Pilkauskas - Comprehensible code
Page 26: Vaidas Pilkauskas - Comprehensible code

LONG LINES

Page 27: Vaidas Pilkauskas - Comprehensible code
Page 28: Vaidas Pilkauskas - Comprehensible code
Page 29: Vaidas Pilkauskas - Comprehensible code
Page 30: Vaidas Pilkauskas - Comprehensible code
Page 31: Vaidas Pilkauskas - Comprehensible code
Page 32: Vaidas Pilkauskas - Comprehensible code
Page 33: Vaidas Pilkauskas - Comprehensible code
Page 34: Vaidas Pilkauskas - Comprehensible code

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

EXAMPLES OF VISUAL NOISE

INCONSISTENCY

UNCONVENTIONAL STYLE

TOOL WARNINGS

EXCESSIVE EMPTY LINES

UNUSED IMPORTS

UNFORMATTED CODE

Page 36: Vaidas Pilkauskas - Comprehensible code
Page 37: Vaidas Pilkauskas - Comprehensible code
Page 38: Vaidas Pilkauskas - Comprehensible code

IGNORING WARNINGS

Page 39: Vaidas Pilkauskas - Comprehensible code

IGNORING WARNINGS

Puts Broken Window into effect

Page 40: Vaidas Pilkauskas - Comprehensible code

IGNORING WARNINGS

False warnings hide important ones

Page 41: Vaidas Pilkauskas - Comprehensible code

IGNORING WARNINGS

Distractions (context switch)Inbox Zero problem

Page 42: Vaidas Pilkauskas - Comprehensible code

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
Page 44: Vaidas Pilkauskas - Comprehensible code
Page 45: Vaidas Pilkauskas - Comprehensible code

ILLOGICAL CODE STRUCTURE

Page 46: Vaidas Pilkauskas - Comprehensible code

LOGICAL STRUCTURE

Group of elements which are in the same level of abstraction

Page 47: Vaidas Pilkauskas - Comprehensible code

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

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

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

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

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

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
Page 54: Vaidas Pilkauskas - Comprehensible code

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

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

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

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

ARGH! BRACES!!1

{ “foo”: “bar”}

<foo> <bar /></foo>

Foo( “bar”)

{ “foo”: “bar”}

<foo> <bar /></foo>

Foo( “bar”)

Page 59: Vaidas Pilkauskas - Comprehensible code

Tools and Formatting

Page 60: Vaidas Pilkauskas - Comprehensible code

val message = ContactActivityMessage(builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))

Page 61: Vaidas Pilkauskas - Comprehensible code

val message = ContactActivity(builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))

Page 62: Vaidas Pilkauskas - Comprehensible code

val message = ContactActivity( builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))

Page 63: Vaidas Pilkauskas - Comprehensible code

val message = ContactActivityMessage( builder.tenantDetails.metaSiteId.getId.asGuid, constructNotifyActivityInfoDto(userActivity), constructNotifyContactInfoDto(contact))

Page 64: Vaidas Pilkauskas - Comprehensible code

Examples

Page 65: Vaidas Pilkauskas - Comprehensible code

val asSiteContact = contact.details.asSiteContact(count) .copy(lastActivity = updated)

// BAD: Chain logic group split

Page 66: Vaidas Pilkauskas - Comprehensible code

val asSiteContact = contact.details.asSiteContact(count).copy(lastActivity = updated)

// GOOD: Chaining on the same line

Page 67: Vaidas Pilkauskas - Comprehensible code

val asSiteContact = contact .details .asSiteContact(count) .copy(lastActivity = updated)

// GOOD: Chain member per line

Page 68: Vaidas Pilkauskas - Comprehensible code

enum State { READ, WRITE, PAUSE, STOP}

// BAD: Broken logical group

Page 69: Vaidas Pilkauskas - Comprehensible code

enum State { READ, WRITE, PAUSE, STOP}

// WORSE: Looks clean, but has broken logical group

Page 70: Vaidas Pilkauskas - Comprehensible code

enum State { READ, WRITE, PAUSE, STOP}

enum State { READ, WRITE, PAUSE, STOP}

// GOOD

Page 71: Vaidas Pilkauskas - Comprehensible code

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

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

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

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

CAN STRUCTURE BE AUTOMATED?

Concentrate on communicating intent,but Automate repetitive work

Page 76: Vaidas Pilkauskas - Comprehensible code

There are other ways to communicate

Page 77: Vaidas Pilkauskas - Comprehensible code
Page 78: Vaidas Pilkauskas - Comprehensible code

CODE COMPREHENSIONis based on

NAMED ABSTRACTIONS and CODE STRUCTURE

Page 79: Vaidas Pilkauskas - Comprehensible code

THANK YOU!

Page 80: Vaidas Pilkauskas - Comprehensible code

QUESTIONS?