diff --git a/code_convention.md b/code_convention.md new file mode 100644 index 0000000..6ca0b69 --- /dev/null +++ b/code_convention.md @@ -0,0 +1,228 @@ +# Code Convention + + + +## binding 생성 κ΄€λ ¨ + +```kotlin + +lateinit var binding: ActivityMainBinding + +override fun onCreate(...) { + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) +} +``` + +## μ€‘λ³΅μ½”λ“œ +μ€‘λ³΅λœ μ½”λ“œκ°€ 있으면 μΆ”ν›„ μœ μ§€λ³΄μˆ˜κ°€ μ–΄λ ΅κ³ , λ³€κ²½ μ‹œ μ‹€μˆ˜ν•  κ°€λŠ₯성이 μ»€μ§€λ―€λ‘œ ν”Όν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. κ³΅ν†΅λœ λ‘œμ§μ€ Util 클래슀둜 λΉΌμ„œ μž¬μ‚¬μš©μ„±μ„ λ†’μ΄λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. λ˜ν•œ λ©”μ†Œλ“œμ˜ κΈΈμ΄λŠ” λ„ˆλ¬΄ κΈΈλ©΄ 가독성이 λ–¨μ–΄μ§€λ―€λ‘œ, 10~20라인 μ •λ„λ‘œ μœ μ§€ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. + +- μ€‘λ³΅μ½”λ“œ 제거 μ „ + ```kotlin + fun showErrorDialog(context: Context) { + AlertDialog.Builder(context) + .setTitle("Error") + .setMessage("An error occurred.") + .setPositiveButton("OK") { dialog, _ -> dialog.dismiss() } + .show() + } + + fun showSuccessDialog(context: Context) { + AlertDialog.Builder(context) + .setTitle("Success") + .setMessage("Operation completed successfully.") + .setPositiveButton("OK") { dialog, _ -> dialog.dismiss() } + .show() + } + ``` + +- μ€‘λ³΅μ½”λ“œ 제거 ν›„(use util) + ```kotlin + fun showDialog( + context: Context, + title: String, + message: String, + positiveButtonText: String = "OK" + ) { + AlertDialog.Builder(context) + .setTitle(title) + .setMessage(message) + .setPositiveButton(positiveButtonText) { dialog, _ -> dialog.dismiss() } + .show() + } + + fun showErrorDialog(context: Context) { + showDialog(context, title = "Error", message = "An error occurred.") + } + + fun showSuccessDialog(context: Context) { + showDialog(context, title = "Success", message = "Operation completed successfully.") + } + ``` + +## Scope ν•¨μˆ˜ +Scope ν•¨μˆ˜(let, apply, run, also, with)λŠ” κ°μ²΄λ‚˜ λ‘œμ§μ„ κ°„κ²°ν•˜κ²Œ μ²˜λ¦¬ν•˜κ³ , 가독성을 높일 수 μžˆλ„λ‘ λ„μ™€μ€λ‹ˆλ‹€. μ μ ˆν•œ Scope ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ€‘μš”ν•˜λ©°, μ½”λ“œ 가독성 및 λͺ…확성을 μœ μ§€ν•΄μ•Ό ν•©λ‹ˆλ‹€. +```kotlin +// let μ˜ˆμ‹œ +val user = api.getUser() +user?.let { + // it을 톡해 user 객체λ₯Ό μ•ˆμ „ν•˜κ²Œ μ‚¬μš© + println(it.name) +} + +// apply μ˜ˆμ‹œ +val view = TextView(context).apply { + text = "Hello" + textSize = 20f + setTextColor(Color.BLACK) +} + +// run μ˜ˆμ‹œ +val result = run { + val x = 10 + val y = 20 + x + y // λ§ˆμ§€λ§‰ 라인이 λ°˜ν™˜κ°’ +} +``` + + +## μƒμˆ˜ +ν•˜λ“œμ½”λ”©λœ 값은 μ˜λ„λ₯Ό νŒŒμ•…ν•˜κΈ° μ–΄λ ΅κ³ , μœ μ§€λ³΄μˆ˜κ°€ μ–΄λ €μšΈ 수 μžˆμœΌλ―€λ‘œ μƒμˆ˜λ‘œ μ •μ˜ν•΄μ„œ κ΄€λ¦¬ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. λ˜ν•œ, 의미 μžˆλŠ” 이름을 λΆ€μ—¬ν•΄ μ½”λ“œ 가독성을 높일 수 μžˆμŠ΅λ‹ˆλ‹€. + +- ν•˜λ“œμ½”λ”©λœ μƒμˆ˜: + ``` + kotlin + fun setTextSize(textView: TextView) { + textView.textSize = 16f // ν•˜λ“œμ½”λ”©λœ 숫자 + } + ``` + +- μƒμˆ˜ν™”λœ μ½”λ“œ + ```kotlin + const val DEFAULT_TEXT_SIZE = 16f + + fun setTextSize(textView: TextView) { + textView.textSize = DEFAULT_TEXT_SIZE // μƒμˆ˜ μ‚¬μš© + } + ``` + +## μ£Όμ„μ˜ μœ„μΉ˜ + +ν•¨μˆ˜ μ£Όμ„μ˜ μœ„μΉ˜ + +```kotlin +// λͺ¨λ“  주석은 ν•¨μˆ˜ μ„ μ–Έ λ°”λ‘œ μœ„μ— +fun foo(f: Any) { + ... +} + +/** + * μ—¬λŸ¬ 쀄일 κ²½μš°μ—λŠ” + * 이 ν˜•μ‹μœΌλ‘œ + */ +fun bar(b: Bar) { + .. +} +``` + +## ν•¨μˆ˜ νŒŒλΌλ―Έν„° + +2개 μ΄ν•˜μΌ 경우 ν•œ 쀄에 + +```kotlin +fun foo(a: Int, t: List) { + ... +} +``` + +3개 이상일 경우 μ—¬λŸ¬ μ€„λ‘œ split + +```kotlin +fun bar( + b: Float, + a: List>, + c: Context, // trailing comma λ„£κΈ° +) { + ... +} +``` + +## ν•¨μˆ˜ νŒŒλΌλ―Έν„°μ˜ μš°μ„ μˆœμœ„ + +- 1μˆœμœ„: 기본값이 μ—†λŠ” νŒŒλΌλ―Έν„° +- 2μˆœμœ„: Modifier (+modiferλŠ” 기본값을 λ„£μ–΄μ£ΌκΈ°) + +```kotlin +fun Switch( + onToggle: (SwitchState) -> Unit, + modifier: Modifier = Modifier, + switchState: SwitchState = SwitchState.Unselected +) +``` + +## 🚨 λ§Žμ€ νŒŒλΌλ―Έν„° vs 객체 자체λ₯Ό λ„˜κΈ°κΈ° +- λ…Όμ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€! + +## μ€‘κ΄„ν˜Έ + +if, for, when 브랜치, do 및 while λ¬Έκ³Ό ν‘œν˜„μ‹μ˜ 경우 본문이 λΉ„μ–΄ μžˆκ±°λ‚˜ 단일 ꡬ문만 ν¬ν•¨ν•˜λŠ” κ²½μš°μ—λ„ μ€‘κ΄„ν˜Έκ°€ ν•„μš”ν•©λ‹ˆλ‹€. + +```kotlin +if (string.isEmpty()) + return // WRONG! + +if (string.isEmpty()) { + return // Okay +} + +if (string.isEmpty()) return // WRONG +else doLotsOfProcessingOn(string, otherParametersHere) + +if (string.isEmpty()) { + return // Okay +} else { + doLotsOfProcessingOn(string, otherParametersHere) +} +``` + +λΉˆλΈ”λŸ­λ„ μ€‘κ΄„ν˜Έ μ΄ν›„μ—λŠ” enterν•΄μ•Όν•©λ‹ˆλ‹€. + +```kotlin +try { + doSomething() +} catch (e: Exception) {} // WRONG! + +try { + doSomething() +} catch (e: Exception) { +} // Okay +``` + + +## ν‘œν˜„μ‹ + +ν‘œν˜„μ‹μœΌλ‘œ μ‚¬μš©λ˜λŠ” if/else μ‘°κ±΄λ¬Έμ—μ„œλŠ” 전체 ν‘œν˜„μ‹μ΄ ν•œ 쀄에 λ“€μ–΄κ°€λŠ” κ²½μš°μ—λ§Œ μ€‘κ΄„ν˜Έλ₯Ό μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. + +```kotlin +val value = if (string.isEmpty()) 0 else 1 // Okay + +val value = if (string.isEmpty()) // WRONG! + 0 +else + 1 + +val value = if (string.isEmpty()) { // Okay + 0 +} else { + 1 +} +``` + + + +## reference +- https://it-techtree.tistory.com/entry/codesmell-refactoring +- https://github.com/PRNDcompany/android-style-guide \ No newline at end of file