μμ±μΌ: 2019.12.05
μλ¬Έ Functional Programming for Android Developers — Part 1μ λ²μν κΈμ λλ€.
μ΄ μ리μ¦μμλ, Functional Programming (FP)μ κΈ°μ΄μ μλ°(good old Java)μ μ½νλ¦°(new awesome Kotlin)μμ μ΄λ»κ² μ°λμ§λ₯Ό λ°°μ°λ €κ³ ν©λλ€. μ΅λν μ΄λ‘ μ μΈ μ λ¬Έ μ©μ΄λ νΌν΄μ μ€μ©μ μΈ κ°λ μ λ€λ£¨κ² μ΅λλ€.
FPλ λ§€μ° ν° μ£Όμ λΌμ Android μ½λμμ μ μ©νκ² μΈ μ μλ κ°λ κ³Ό λ°©λ² μ λλ§ λ€λ£¨λ €κ³ ν©λλ€. Androidμμ μ¬μ©ν μ μλ κ°λ λ μ‘°κΈ λμ€κΈ΄ νκ² μ§λ§ μ΅λν κ΄λ ¨μλ λ΄μ©λ§ λ€λ£¨λλ‘ νκ² μ΅λλ€.
μ€λΉλμ ¨λμ? Let’s go!
Functional Programmingμ΄λ 무μμ΄κ³ , μ μ¬μ©ν΄μΌ νλμ?
μ’μ μ§λ¬Έμ λλ€. Functional Programmingμ΄λΌλ μ©μ΄λ λμ λ²μμ νλ‘κ·Έλλ° κ°λ μ λ΄κ³ μμ΅λλ€. κ·Έ ν΅μ¬μ νλ‘κ·Έλ¨μ μνμ ν¨μμ κ³μ°μΌλ‘ λ€λ£¨κ³ mutable μνμ μ¬μ΄λ μ΄ννΈλ₯Ό λ°©μ§νλ κ²μ λλ€(μμΌλ‘ μΆ©λΆν λ€λ£¨κ² λ λ΄μ©μ λλ€).
FPκ° ν΅μ¬μ μΌλ‘ κ°μ‘°νλ λ΄μ©μ:
- μ μΈμ μ½λ : νλ‘κ·Έλλ¨Έλ whatμ λν΄ μ κ²½μ¨μΌ νκ³ , μ»΄νμΌλ¬μ λ°νμμ΄ howμ λν΄ μ κ²½μ°λλ‘ ν΄μΌ ν©λλ€.
- λͺ νμ± : μ½λλ μ΅λν μ΄ν΄νκΈ° μ¬μμΌ ν©λλ€. νΉν, μμμΉ λͺ»ν μ΄μλ₯Ό λ°©μ§νλ €λ©΄ μ¬μ΄λ μ΄ννΈλ λΆλ¦¬λμ΄μΌ ν©λλ€. λ°μ΄ν° νλ‘μ°μ μλ¬ νΈλ€λ§μ λͺ μμ μ΄μ΄μΌ νκ³ GOTOμ Exceptionκ°μ ꡬ쑰λ μ±μ΄ μλνμ§ μμ μνκ° λ μ μκΈ° λλ¬Έμ μ§μν΄μΌ ν©λλ€.
- λμμ± : ν¨μμ μμμ±(functional purity)μ΄λΌλ κ°λ λλ¬Έμ κ°μ₯ ν¨μμ μΈ(functional) μ½λλ κΈ°λ³Έμ μΌλ‘ λμμ±μ κ°μ΅λλ€. μ΄λ° νΉμ±μ΄ FPμ μΈκΈ°λ₯Ό λμ΄κ³ μμ΅λλ€. CPU μ½μ΄κ° μ¬μ©λλ κ²λ§νΌ 맀λ λΉ¨λΌμ§μ§λ μκ³ , λ©ν° μ½μ΄ μν€ν μ²μ μ₯μ μ κ°κΈ° μν΄ νλ‘κ·Έλ¨μ λ concurrentνκ² λ§λ€μ΄μΌ νκΈ° λλ¬Έμ λλ€.
- Higher Order Functions : ν¨μλ λ€λ₯Έ μΈμ΄μ primitiveμ²λΌ 첫λ²μ§Έ ν΄λμ€ λ©€λ²μ λλ€. Stringμ΄λ intμ²λΌ ν¨μλ₯Ό μ λ¬ν μ μμ΅λλ€.
- λΆλ³μ±(Immutability) : λ³μλ ν λ² μ΄κΈ°νλ ν μμ λμ§ μμ΅λλ€. ν λ³μκ° μμ±λλ©΄, μμν λ°λμ§ μμ΅λλ€. λ³κ²½μ μνλ€λ©΄, μλ‘ μμ±ν΄μΌ ν©λλ€. μ΄κ²μ΄ λͺ μμ±κ³Ό μ¬μ΄λ μ΄ννΈ λ°©μ§μ λ λ€λ₯Έ μΈ‘λ©΄μ λλ€. μ΄λ€ κ°μ΄ λ³νν μ μλ€λ νΉμ±μ μλ©΄, κ·Έ κ°μ μ¬μ©ν λ κ±±μ νμ§ μμλ λ©λλ€.
μ μΈμ , λͺ μμ μ΄κ³ concurrentν μ½λλ μ½λ νμ λ° μκΈ°μΉ λͺ»ν μν©μ νΌνκΈ° μν μ€κ³κ° λ μ½μ§ μμκΉμ?
첫λ²μ§Έ ννΈμμλ FPμμ κ°μ₯ κΈ°λ³Έμ μΈ κ°λ λΆν° μμν©λλ€: Purity, Side effects, Ordering.
Pure functions
ν¨μμ κ²°κ³Όκ° μ λ ₯μλ§ μμ‘΄νκ³ μ¬μ΄λ μ΄ννΈκ° μμ λ(μ¬μ΄λ μ΄ννΈλ λ°λ‘ λ€μμ λ€λ£Ήλλ€) κ·Έ ν¨μλ μμ(pure)νλ€κ³ ν©λλ€. μμλ₯Ό λ³ΌκΉμ?
μ΄ κ°λ¨ν ν¨μλ λ μλ₯Ό λνλ ν¨μμ λλ€. μ«μ νλλ νμΌμμ μ½κ³ , λ€λ₯Έ μ«μλ νλΌλ―Έν°λ‘ μ λ¬λ©λλ€.
Java
int add(int x) {
int y = readNumFromFile();
return x + y;
}
Kotlin
fun add(x: Int): Int {
val y: Int = readNumFromFile()
return x + y
}
μ΄ ν¨μμ κ²°κ³Όλ μ λ ₯μλ§ μμ‘΄νκ³ μμ§ μμ΅λλ€. readNumFromFile()μ κ²°κ³Όμλ μμ‘΄νκ³ μμ΄μ, xκ° κ°μλ λ€λ₯Έ κ²°κ³Όκ° λμ¬ μ μμ΅λλ€. μ΄λ° ν¨μκ° λΉμμ(impure)ν¨μμ λλ€.
κ·ΈλΌ μ΄ ν¨μλ₯Ό μμ ν¨μλ‘ μμ ν΄λ΄ μλ€.
Java
int add(int x, int y) {
return x + y;
}
Kotlin
fun add(x: Int, y: Int): Int {
return x + y
}
μ΄μ ν¨μμ κ²°κ³Όλ μ λ ₯μλ§ μμ‘΄μ μ λλ€. μ£Όμ΄μ§ xμ yμ λν΄ ν¨μλ νμ κ°μ κ²°κ³Όλ₯Ό λ°νν κ²μ λλ€. μ΄μ μ΄ ν¨μλ μμν¨μλΌκ³ ν μ μμ΅λλ€. μνμμμ ν¨μ λν κ°μ λ°©μμ λλ€. μνμ ν¨μμ κ²°κ³Όλ μ λ ₯μλ§ μμ‘΄μ μ λλ€γ ‘κ·Έλμ FPλ μΌλ°μ μΌλ‘ μ°λ¦¬κ° μ¬μ©νλ νλ‘κ·Έλλ° μ€νμΌλ³΄λ€λ μνμ λ κ°κΉμ΅λλ€.
P.S. λΉ μ λ ₯κ°λ μ λ ₯μ λλ€. ν¨μμ μ λ ₯κ°μ΄ μμΌλ©΄μ νμ κ°μ κ²°κ³Όλ₯Ό λ°ννλ€λ©΄, κ·Έκ² λν μμ ν¨μμ λλ€.
P.P.S. μ£Όμ΄μ§ μ λ ₯μ λν΄ νμ κ°μ κ²°κ³Όλ₯Ό λ΄λ νΉμ±μ μ°Έμ‘° ν¬λͺ μ±(referential transparency)μ΄λΌκ³ νλ©°, μλ§ μμ ν¨μμ λν μ€λͺ μ λ³Ό λ λ³Έ μ μ΄ μλ μ©μ΄μΌ κ²λλ€.
Side effects
κ°μ λ§μ ν¨μλ‘ μ¬μ΄λ μ΄ννΈ κ°λ μ λν΄ μ΄ν΄λ΄ μλ€. κ²°κ³Όλ₯Ό νμΌμ μ°λ κ²μΌλ‘ λ°κΏλ³΄κ² μ΅λλ€.
Java
int add(int x, int y) {
int result = x + y;
writeResultToFile(result);
return result;
}
Kotlin
fun add(x: Int, y: Int): Int {
val result = x + y
writeResultToFile(result)
return result
}
μ΄ ν¨μλ μ΄μ κ³μ° κ²°κ³Όλ₯Ό νμΌμ μ°κ³ μμ΅λλ€. μ¦, ν¨μ λ°μ μνλ₯Ό λ°κΎΈκΈ° μμνμ΅λλ€. μ΄ ν¨μλ μ΄μ μ¬μ΄λ μ΄ννΈλ₯Ό κ°μ§κ³ , λ μ΄μ μμ ν¨μλ μλλλ€.
λ²μ λ°μ μνλ₯Ό λ³κ²½νλ λͺ¨λ μ½λ—βλ³μ μμ , νμΌ μ°κΈ°, DB μ μ₯, 무μΈκ° μμ λ±β—λ λͺ¨λ μ¬μ΄λ μ΄ννΈλ₯Ό κ°λλ€κ³ ν μ μμ΅λλ€.
FPμμλ μ¬μ΄λ μ΄ννΈλ₯Ό κ°λ ν¨μλ λ μ΄μ μμ ν¨μκ° μλκ³ , μ΄μ 컨ν μ€νΈμ μμ‘΄μ μ΄κΈ° λλ¬Έμ μ§μ λμμ λλ€. μ½λμ 컨ν μ€νΈλ μ€μ€λ‘ κ°μ§ μμμ μΆλ‘ νκΈ°κ° λ μ΄λ ΅μ΅λλ€.
μΊμλ₯Ό λ°λΌλ³΄λ μ½λμ μΌλΆλ₯Ό μμ±νλ€κ³ κ°μ ν΄λ³΄μΈμ. κ·Έ μ½λλ λκ΅°κ° μΊμμ μΌλμ§, 무μμ μΌλμ§, μΈμ μΌλμ§, κ·Έ λ°μ΄ν°κ° μ ν¨νμ§ λ±μ μμ‘΄νκ² λ©λλ€. μΊμμ λͺ¨λ μνλ₯Ό μ΄ν΄νμ§ μκ³ μλ νλ‘κ·Έλ¨μ΄ 무μμ νκ³ μλμ§ μ΄ν΄ν μ μμ΅λλ€. λ§μ½ μ΄κ±Έ λ νμ₯ν΄μ λ€λ₯Έ κ²½μ°λ€β—βλ€νΈμν¬, DB, νμΌ, μ¬μ©μ μ λ ₯ λ±γ ‘μ μμ‘΄μ μΈ μ±μ λ§λ λ€λ©΄, μ νν μ΄λ»κ² λμνκ³ μλμ§ μκΈ° νλ€κ³ λͺ¨λ λΆλΆμ ν λ²μ μ΄ν΄νκΈ°λ νλ€μ΄ μ§λλ€.
κ·ΈλΌ μ΄ λ§μ΄ λ€νΈμν¬, λ°μ΄ν°λ² μ΄μ€, μΊμκ°μ κ±Έ μ°μ§ λ§λΌλ κ±ΈκΉμ? λΉμ°ν μλλλ€. λ³΄ν΅ μ½λμ μ€νμ΄ λλ¬μ λ μ΄λ€ λμμ΄ μλ£λλ κ²μ΄ λͺ©μ μΌν λ° Android μ±μ κ²½μ°, λ³΄ν΅ UI μ λ°μ΄νΈλ₯Ό μλ―Έν©λλ€.
FPμ μ£Όμ κ°λ μ μ¬μ΄λ μ΄ννΈλ₯Ό μμ ν μμ μλ κ² μλλΌ, ν¬ν¨νμ§λ§ λΆλ¦¬μν€λ κ²μ λλ€. μ¬μ΄λ μ΄ννΈλ₯Ό κ°λ ν¨μλ€λ‘ μ½λλ₯Ό λλ½νκΈ° 보λ€λ, μ¬μ΄λ μ΄ννΈλ₯Ό μμ€ν μ ꡬμμΌλ‘ λͺ°μλμ μ΅μνμ μν₯λ§ κ°κ³ , νμ νκΈ° λ μ¬μμ§λλ‘ νλ κ²λλ€. μ΄ λΆλΆμ λν΄μλ λ€μ ννΈμμ functional architectureλ₯Ό λ μμΈν μμλ³Ό κ²μ λλ€.
Ordering
μ¬μ΄λ μ΄ννΈκ° μλ μμ ν¨μμ λ¬Άμμ κ°μ§κ³ μμΌλ©΄, ν¨μκ° μ€νλλ μμλ μκ΄ μμ΄μ§λλ€.
λ΄λΆμ μΌλ‘ 3κ°μ μμ ν¨μλ₯Ό νΈμΆνλ ν¨μ νλλ₯Ό κ°μ ν΄λ΄ μλ€:
Java
void doThings() {
doThing1();
doThing2();
doThing3();
}
Kotlin
fun doThings() {
doThing1()
doThing2()
doThing3()
}
μ΄ ν¨μλ€μ΄ (ν ν¨μμ κ²°κ³Όκ° λ€λ₯Έ ν¨μμ μ λ ₯μ΄ μλκΈ° λλ¬Έμ) μλ‘ λ 립μ μ΄κ³ , (μμν¨μμ΄κΈ° λλ¬Έμ) μμ€ν μ μ΄λ€ κ²λ λ°κΎΈμ§ μλλ€λ κ²μ΄ λΆλͺ ν λ³΄μΌ κ²μ λλ€. μ΄κ²μ μ΄ ν¨μλ€μ΄ μ€νλλ μμκ° μμ ν λ°λ μ μκ² ν΄μ€λλ€.
λ 립μ μΈ μμ ν¨μλ€μ΄κΈ° λλ¬Έμ μ€ν μμλ λ€μ μμ΄κ³ μ΅μ νλ μ μμ΅λλ€. λ§μ½ doThing2()μ μ λ ₯κ°μ΄ doThing1()μ κ²°κ³Όκ°μ΄ λλ©΄, μ΄ λ ν¨μλ μμλλ‘ μ€νλμ΄μΌ νμ§λ§ doThing3()λ doThing1() μ€ν μ μΌλ‘ μ¬μ ν μ¬λ°°μΉ κ°λ₯ν©λλ€.
μ΄λ° μμ νΉμ±μ μ΄λ€ μ₯μ μ μ€κΉμ? λ°λ‘ Concurrency! μμκ° μμ΄λ κ²μ λν κ±±μ μμ΄ μ΄ ν¨μλ€μ 3κ°μ λ³λ CPU μ½μ΄μμ μ€νν μ μμ΅λλ€!
λλΆλΆ ν₯μλ μμ ν¨μν μΈμ΄(μ, Haskell)μ μ»΄νμΌλ¬λ λ³΄ν΅ μ½λλ₯Ό λΆμνμ¬ concurrentμΈμ§ μλμ§ μλ €μ£Όκ³ , deadlocks, race conditions κ°μ κ²½μ°μλ λ°λ‘ μ μ μκ² μ€μ§μν¬ μ μμ΅λλ€. λν μ΄λ° μ»΄νμΌλ¬λ€μ μ΄λ‘ μ μ½λλ₯Ό μλμΌλ‘ λ³λ ¬νν μ μμ΅λλ€(μ΄κ±΄ μ¬μ€ μ κ° μλ μ΄λ€ μ»΄νμΌλ¬μλ μ‘΄μ¬νμ§ μμ§λ§ μ°κ΅¬ μ§νμ€μ λλ€).
μ¬λ¬λΆμ μ»΄νμΌλ¬κ° μ΄λ° μ μ κ²μ¬νμ§ μλλΌλ, ν¨μ μκ·Έλμ²λ₯Ό λ³΄κ³ μ½λκ° concurrentμΈμ§ μλμ§ νμ ν μ μκ³ , μ¨κ²¨μ§ μ¬μ΄λ μ΄ννΈλ‘ κ°λν μ½λλ₯Ό λ³λ ¬ννλλ‘ λ Έλ ₯νλ©΄ μ€μ²©λ μ€λ λ© λ²κ·Έλ₯Ό λ°©μ§ν μ μμ΅λλ€.
Summary
첫λ²μ§Έ ννΈκ° FPμ λν μ¬λ¬λΆμ ν₯λ―Έλ₯Ό λ μ μμμΌλ©΄ μ’κ² μ΅λλ€. μμν¨μμ΄λ©΄μ μ¬μ΄λ μ΄ννΈκ° μλ ν¨μλ μ½λλ₯Ό νμ νκΈ° λ μ½κ² λ§λ€κ³ , concurrencyλ₯Ό λ¬μ±νκΈ° μν 첫 κ±Έμμ λλ€.
concurrencyμ λν΄ λ°°μ°κΈ° μ μ, immutabilityμ λν΄ μμμΌ ν©λλ€. Part 2μμ μμν¨μμ immutabilityκ° μΌλ§λ κ°λ¨νκ³ lockκ³Ό mutex μ μ₯μμ΄ concurrent μ½λλ₯Ό μ΄ν΄νκΈ° μ½κ² μμ±νλ λ° λμμ΄ λλμ§ μμλ³Ό κ²μ λλ€.
'κ°λ° > Android' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Android] Dependency Injection Part 1. Overview (0) | 2021.04.08 |
---|---|
Android κ°λ°μλ₯Ό μν ν¨μν νλ‘κ·Έλλ° Part 2 (0) | 2021.04.08 |
[Android] Kotlin Delegates in Android: Android κ°λ°μ Properties Delegate νμ©νκΈ° (0) | 2021.04.08 |
[Android] Kotlin Extension Functionμ μ¬μ©νμ¬ λλΈ ν΄λ¦ λ°©μ§νκΈ° (0) | 2021.04.08 |
[Android] Jetpack - LiveData (0) | 2021.04.08 |