of code - More than 50 active engineers for only the main repository - Many submodules - Many libraries and dependencies Scaling out code review > Introduction
of code - More than 50 active engineers for only the main repository - Many submodules - Many libraries and dependencies Scaling out code review > Introduction
review... - Heavy review request to only a few reviewers - Uneven review quality Harder to scale code review than code writing Scaling out code review > Introduction
reviewers + higher code visibility - Refuse problematic PRs - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Introduction
reviewers + higher code visibility - Refuse problematic PRs - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Refuse a problematic PR
with stub classes class UserProfilePresenter(profileView: View, profileUseCase: ...) { fun onEditButtonClicked() = TODO() Scaling out code review > Refuse a problematic PR
with stub classes class UserProfilePresenter(profileView: View, profileUseCase: ...) { fun onEditButtonClicked() = TODO() Bottom up approach: Create small classes first data class UserProfileData(val userId: Long, val name: String, ...) Scaling out code review > Refuse a problematic PR
with stub classes class UserProfilePresenter(profileView: View, profileUseCase: ...) { fun onEditButtonClicked() = TODO() Bottom up approach: Create small classes first data class UserProfileData(val userId: Long, val name: String, ...) Describe the future plan in the PR description Scaling out code review > Refuse a problematic PR
reviewers + higher code visibility - Refuse problematic PRs - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Reviewer/reviewee education
Reviewers can be confused about what to comment - "Something smells wrong, but no idea what" - "There are several approches, but which is the best?" Scaling out code review > Reviewer/reviewee education
- Go to review assignee's desk - Share the key idea of what to comment - Take initiative if the partner gets stuck Scaling out code review > Reviewer/reviewee education
review = Assign a senior engineer after a junior approved The junior engineer learns - Which points should be checked - How to reach an agreement with the reviewee Scaling out code review > Reviewer/reviewee education
PRs - Rebalances senior engineer's work load Guarantees few superficial problems - Can focus on fundamental review Scaling out code review > Reviewer/reviewee education
reviewers + higher code visibility - Refuse problematic PRs - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Keep the master branch up to date
consistent - Finite education/development time - Hierarchal team structure - Limitations in tooling Scaling out code review > Keep the master branch up to date
consistent - Finite education/development time - Hierarchal team structure - Limitations in tooling Problematic code may be merged Scaling out code review > Keep the master branch up to date
as soon as possible Merge code to the master branch even if incomplete - Use feature flags instead of feature branch - Merge back release branches to the master branch periodically Scaling out code review > Keep the master branch up to date
+ higher code visibility - Refuse problematic PRs - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Summary
+ higher code visibility - Refuse problematic PRs - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Summary
+ higher code visibility - Ask the reviewee to split PRs, discuss, write a documentation - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Summary
+ higher code visibility - Ask the reviewee to split PRs, discuss, write a documentation - Educate reviewers and reviewees - Keep the master branch up to date Scaling out code review > Summary
+ higher code visibility - Ask the reviewee to split PRs, discuss, write a documentation - Conduct pair/two-phase code review and classroom lectures - Keep the master branch up to date Scaling out code review > Summary
+ higher code visibility - Ask the reviewee to split PRs, discuss, write a documentation - Conduct pair/two-phase code review and classroom lectures - Keep the master branch up to date Scaling out code review > Summary
much time - Use formatters and static analysis tools Idioms: - Use standard libraries as much as possible - Avoid reinventing the wheel What to review > Style/conventions/idioms
var parsedInt = null if (isParseableAsInt(numberString)) { parsedInt = numberString.toInt() } return parsedInt What to review > Style/conventions/idioms
used Bad naming: fun onUserProfileUpdated(userData: UserData, isInMainPage: Boolean) Better naming: fun updateUserNameView(userData: UserData, showsFullName: Boolean) What to review > Natural language
Better documentation: /** * Returns a local file path of the given file ID. * This returns null if an invalid file ID is given. */ What to review > Natural language
class QueryResponse { data class Result(value: String): QueryResponse() data class Error(errorCode: Int): QueryResponse() What to review > Inner type structure
function Bad function design: fun startColorAnimation() = ValueAnimator(...).apply { addUpdateListener { // View color update logic } }.start() What to review > Inner type structure
function Better function design: fun startColorAnimation() { val colorAnimator = ValueAnimator(...) colorAnimator.addUpdateListener(::applyProfileViewColor) colorAnimator.start() } What to review > Inner type structure
the original class class String { // This function looks wrong if defined in the class `String` fun toYourData() = ... Reviewing Kotlin code > Top-level extensions
- Limit the visibility to internal or file/class private - Create an object for a namespace - Change the receiver to the first parameter Reviewing Kotlin code > Top-level extensions
context Example of mutable model class initialization: val userData = UserData().apply { name = "FIRST LAST" age = 20 } Reviewing Kotlin code > Scope functions
scope Example of confusing scope function: var userData: UserData = ... fun setDefaultUserData() = UserData().apply { name = "FIRST LAST" userData = this } Reviewing Kotlin code > Scope functions
scope Example of confusing scope function: var userData: UserData = ... // Hard to distinguish the side effect fun setDefaultUserData() = UserData().apply { name = "FIRST LAST" userData = this // Hard to find the `userData` scope } Reviewing Kotlin code > Scope functions
the context Better example: var userData: UserData = ... fun setDefaultUserData() { // Move the outside modification out of the scope function userData = UserData().apply { name = "FIRST LAST" } Reviewing Kotlin code > Scope functions
Make review easy and code visible; educate reviewers What to review: - Readability first - Not only style/idioms, but also naming/comments/structure... - Kotlin language feature usage Summary