์์ฑ์ - named, factory๋ ์ธ์ ์ฐ๋
์ง๋ ๊ธ๋ค์์ ๊ธฐ๋ณธ ์์ฑ์(UserProfile(this.name))๋ ์ด๋ฏธ ์จ๋ดค๋ค. ๊ทผ๋ฐ ์ค๋ฌด ์ฝ๋์์๋ "์ด ํด๋์ค๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ด ๋ฑ ํ๋"์ธ ๊ฒฝ์ฐ๊ฐ ๋ณ๋ก ์๋ค. ์๋ฅผ ๋ค์ด ์ฌ์ฉ์ ํ๋กํ์ ๋ง๋ค ๋, ์ผ๋ฐ ํ์๊ฐ์
์ผ๋ก ๋ง๋ค ์๋ ์๊ณ , "๊ฒ์คํธ๋ก ์์ํ๊ธฐ"์ฒ๋ผ ์ด๋ฆ ์์ด ๋ง๋ค ์๋ ์๋ค. ์ด๋ด ๋ Kotlin ํ๋ ์ต๊ด๋๋ก ์ง๋ฉด ๋ฐ๋ก ๋งํ๋ค.
class UserProfile {
final String name;
UserProfile(this.name);
UserProfile(); // ์ฌ๊ธฐ์ ์๋ฌ๋จ
}The default constructor is already defined. ์ด? ํ๋ผ๋ฏธํฐ ๊ฐ์๊ฐ ๋ค๋ฅธ๋ฐ ์ ์ ๋์ง? Java๋ Kotlin์ ์ค๋ฒ๋ก๋ฉ(overloading)์ ์ต์ํ๋ฉด ์์ฐ์ค๋ฝ๊ฒ ์ด๋ ๊ฒ ์งค ๊ฒ ๊ฐ๋ค.
์์ธ: Dart๋ "์ด๋ฆ ์๋ ์์ฑ์"๋ฅผ ํด๋์ค๋น ๋ฑ ํ๋๋ง ํ์ฉํ๋ค
Kotlin/Java๋ "ํ๋ผ๋ฏธํฐ ๋ชฉ๋ก์ด ๋ค๋ฅด๋ฉด ๊ฐ์ ์ด๋ฆ์ ํจ์(์์ฑ์)๋ฅผ ์ฌ๋ฌ ๊ฐ ๋ง๋ค ์ ์๋ค"(์ค๋ฒ๋ก๋ฉ)๋ ๊ท์น์ด ์๋ค. Dart๋ ์ด ๊ท์น์ด ์๋ค. UserProfile(...)์ฒ๋ผ ์ด๋ฆ ์์ด ์ฐ๋ ์์ฑ์๋ ํด๋์ค์ ๋ฑ ํ๋๋ง ๊ฐ์ง ์ ์๋ค. ํ๋ผ๋ฏธํฐ ๊ฐ์๊ฐ ๋ฌ๋ผ๋ ์์ฉ์๋ค โ Dart ์
์ฅ์์๋ ๋ ๋ค ๊ทธ๋ฅ "์ด๋ฆ ์๋ ์์ฑ์"๋ผ์, ๋ ๋ฒ์งธ๋ก ์ ์ํ๋ ์๊ฐ "๋ ์ด๋ฏธ ์ ์ํ์์"๋ผ๋ฉฐ ๋ง๋๋ค.
๊ณ ์น ์ฝ๋: ์ด๋ฆ์ ๋ถ์ฌ์ ๊ตฌ๋ถํ๋ค (named constructor)
class UserProfile {
final String name;
UserProfile(this.name); // ๊ธฐ๋ณธ ์์ฑ์
UserProfile.guest() : name = '๊ฒ์คํธ'; // ์ด๋ฆ ๋ถ์ ์์ฑ์
void printName() => print(name);
}
void main() {
final user1 = UserProfile('ํ๊ธธ๋');
final user2 = UserProfile.guest();
user1.printName(); // ํ๊ธธ๋
user2.printName(); // ๊ฒ์คํธ
}UserProfile.guest()์ฒ๋ผ ํด๋์ค ์ด๋ฆ ๋ค์ .์ด๋ฆ์ ๋ถ์ด๋ฉด, ์์ ํ ๋ณ๊ฐ์ ์์ฑ์๋ฅผ ํ๋ ๋ ๋ง๋ค ์ ์๋ค. ์ด๊ฒ named constructor๋ค. UserProfile.guest() : name = '๊ฒ์คํธ'; ๋ถ๋ถ์์ ์ฝ๋ก (:) ๋ค์ ์ค๋ ๊ฑธ initializer list๋ผ๊ณ ๋ถ๋ฅด๋๋ฐ, ํจ์ ๋ชธํต({ })์ด ์๋๋ผ **"ํ๋์ ๊ฐ์ ๋์
ํ๋ ์ ์ฉ ์ฌ๋กฏ"**์ด๋ค. ์ด ์๋ฆฌ๋ ๊ท์น์ด ๋ฑ ํ๋๋ค โ ํํ์ ํ๋๋ง ์ฌ ์ ์๋ค.
๊ทผ๋ฐ initializer list์ ๋ณต์กํ ๋ก์ง์ ๋ชป ๋ฃ๋๋ค
class UserProfile {
final String name;
UserProfile.fromJson(Map<String, dynamic> json)
: name = json['name'] ?? '์ด๋ฆ์์'; // ํํ์ ํ๋ - ์ด๊ฑด ๋จ
}์ด ์ ๋ ?? ์ฒ๋ฆฌ๋ ๊ด์ฐฎ์๋ฐ, ์ฌ๊ธฐ์ ๋ก๊ทธ๋ฅผ ์ฐ๊ฑฐ๋, ์ฌ๋ฌ ์ค์ ๊ฑธ์ณ ๊ฐ์ ๊ฒ์ฆํ๊ฑฐ๋, ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ค๋ฅธ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์ถ์ผ๋ฉด? initializer list๋ ํํ์ ํ๋๋ง ํ์ฉํด์ ์ ๋๋ค. ํจ์ ๋ชธํต์ด ์๋๋๊น, if๋ฌธ์ด๋ print ๊ฐ์ ์ฌ๋ฌ ์ค ์ฝ๋๋ฅผ ๊ทธ ์๋ฆฌ์ ๊ทธ๋ฅ ๋ฃ์ ์๊ฐ ์๋ค.
์ฌ๊ธฐ์ factory ์์ฑ์๊ฐ ๋์จ๋ค
class UserProfile {
final String name;
UserProfile._(this.name); // ์ด๋ฆ ์์ _ ๋ฅผ ๋ถ์ฌ์ ์ธ๋ถ์์ ์ง์ ๋ชป ๋ง๋ค๊ฒ ๋ง์
factory UserProfile.fromJson(Map<String, dynamic> json) {
print('ํ์ฑ ์์'); // ์ฌ๋ฌ ์ค ๋ก์ง ์์ ๋กญ๊ฒ ๊ฐ๋ฅ
final rawName = json['name'];
if (rawName == null || rawName.toString().isEmpty) {
return UserProfile._('์ด๋ฆ์์');
}
return UserProfile._(rawName);
}
}
void main() {
final user = UserProfile.fromJson({'name': ''});
print(user.name); // ์ด๋ฆ์์
}factory๋ฅผ ๋ถ์ด๋ฉด, ์ด ์์ฑ์๋ ๋ชธํต์ด ์ผ๋ฐ ํจ์์ฒ๋ผ ์์ ๋ก์์ง๋ค. if, ๋ฐ๋ณต๋ฌธ, ์ฌ๋ฌ ์ค ๋ก๊ทธ, ๋ญ๋ ๋ฃ์ ์ ์๊ณ , ๋ง์ง๋ง์ return์ผ๋ก ์ค์ ๊ฐ์ฒด๋ฅผ ํ๋ ๊ณจ๋ผ์ ๋๋ ค์ฃผ๋ฉด ๋๋ค.
์ฌ๊ธฐ์ ์ค์ ๋ก ๊ฐ์ ์ฑ์ฐ๋ ์์ฑ์๋ UserProfile._(this.name) ํ๋๋ฟ์ด๋ค. _๋ฅผ ๋ถ์ธ ์ด์ ๊ฐ "์ด ์ง์ง ์์ฑ์๋ ์ธ๋ถ์์ ์ง์ ๋ชป ๋ถ๋ฅด๊ฒ ์ ๊ฐ๋ผ"๋ ๋ป์ด๋ค. factory UserProfile.fromJson(...)์ ๊ทธ ์์ฒด๊ฐ ๊ฐ์ ์ฑ์ฐ๋ ๊ฒ ์๋๋ผ, ๊ฐ์ ๋ค๋ฌ์ ๋ค์ ์ง์ง ์์ฑ์๋ฅผ ๋์ ํธ์ถํด์ฃผ๋ ์ฐฝ๊ตฌ ์ญํ ๋ง ํ๋ค. ์ฆ "๋ง๋๋ ๋ฐฉ๋ฒ์ด ์ฌ๋ฌ ๊ฐ"๋ผ๋ ๊ฑด ๊ฐ์ ์ฑ์ฐ๋ ๋ก์ง ์์ฒด๊ฐ ์ฌ๋ฌ ๊ฐ๋ผ๋ ๋ป์ด ์๋๋ผ, ํ๋๋ฟ์ธ ๊ทธ ๋ก์ง์ผ๋ก ๋ค์ด๊ฐ๋ ๋ฌธ(์ง์
๋ก)์ด ์ฌ๋ฌ ๊ฐ๋ผ๋ ๋ป์ด๋ค.
Dart์ _๋ "ํด๋์ค ๋น๊ณต๊ฐ"๊ฐ ์๋๋ผ ํ์ผ ๋น๊ณต๊ฐ๋ค. ๊ฐ์ ํ์ผ ์์ด๋ฉด UserProfile._(...)๋ ์ง์ ํธ์ถ์ด ๋๊ธด ํ๋๋ฐ, ์ค๋ฌด์์๋ ํด๋์ค๋ฅผ ๋ณดํต ๋ณ๋ ํ์ผ๋ก ๋ถ๋ฆฌํด์ ์ฐ๋๊น ์ฌ์ค์ ์ธ๋ถ์์ ๋งํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
named vs factory, ์ธ์ ๋ญ ์ฐ๋
- named constructor: ๋ง๋๋ ๋ฐฉ๋ฒ์ด ์ฌ๋ฌ ๊ฐ์ง์ธ๋ฐ, ๊ฐ ๋ฐฉ๋ฒ์ด ๊ฐ๋จํ ๊ฐ ๋์
์ ๋(ํํ์ ํ๋)์ผ ๋.
UserProfile.guest()์ฒ๋ผ ์ด๋ฆ์ผ๋ก ์๋๋ฅผ ๋๋ฌ๋ด๊ณ ์ถ์ ๋. - factory constructor: ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ ์ ๊ฒ์ฆ/๋ณํ/๋ถ๊ธฐ ๊ฐ์ ์ฌ๋ฌ ์ค ๋ก์ง์ด ํ์ํ๊ฑฐ๋, ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฐ์ ๊ณจ๋ผ ๋๋ ค์ฃผ๊ณ ์ถ์ ๋.
์ค๋ฌด์์๋ fromJson์ฒ๋ผ ์๋ฒ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ฐ๊พธ๋ ์๋ฆฌ์ factory๊ฐ ์ ๋ง ์์ฃผ ๋ฑ์ฅํ๋ค. API ์๋ต์ ๋ค๋ฃจ๊ธฐ ์์ํ๋ฉด ๊ฑฐ์ ํญ์ ์ด ํจํด์ ์ฐ๊ฒ ๋๋ค.
Kotlin๊ณผ ๋น๊ตํ๋ฉด
Kotlin์ named/factory์ฒ๋ผ "์์ฑ์์ ์ด๋ฆ์ ๋ถ์ด๋" ๋ฌธ๋ฒ ์์ฒด๊ฐ ์๋ค. ๋์ ์ด๋ฐ ์์ผ๋ก ํ๋ด๋ธ๋ค.
class UserProfile private constructor(val name: String) {
companion object {
fun guest(): UserProfile = UserProfile("๊ฒ์คํธ")
fun fromJson(json: Map<String, Any?>): UserProfile {
println("ํ์ฑ ์์")
val rawName = json["name"] as? String
return if (rawName.isNullOrEmpty()) {
UserProfile("์ด๋ฆ์์")
} else {
UserProfile(rawName)
}
}
}
}
val user1 = UserProfile.guest()
val user2 = UserProfile.fromJson(mapOf("name" to ""))companion object์์guest(),fromJson()์ ์ง์ง ์์ฑ์๊ฐ ์๋๋ผ ๊ทธ๋ฅ ํ๋ฒํ ํจ์๋ค. ๋ค๋ง ์์์ ์ง์ง ์์ฑ์(UserProfile(val name: String))๋ฅผ ๋์ ํธ์ถํด์ฃผ๋ ์ฐฝ๊ตฌ ์ญํ ์ ํ๋ค โ Dart์ factory๊ฐ ํ๋ ์ผ๊ณผ ๋๊ฐ๋ค.private constructor๋ Dart์_์ ๊ฐ์ ๋ชฉ์ ์ด๋ค. "์ง์ง ์์ฑ์๋ ๋ชป ๋ถ๋ฅด๊ฒ ๋ง๊ณ , companion object์ ํจ์๋ก๋ง ๋ง๋ค๊ฒ ํ์."- Kotlin์๋ initializer list์ฒ๋ผ "ํํ์ ํ๋๋ง ๋๋" ์ ์ฝ๋ ์ฌ๋กฏ๋ ์๋ค. ๋์
init๋ธ๋ก์ด ์๋๋ฐ, ์ด๊ฑด ์ฒ์๋ถํฐ ์ฌ๋ฌ ์ค,print,if๋ค ์์ ๋กญ๊ฒ ๋ค์ด๊ฐ๋ค.
class UserProfile(rawName: String?) {
val name: String
init {
println("ํ์ฑ ์์")
name = rawName ?: "์ด๋ฆ์์"
}
}๊ทธ๋์ Dart์ฒ๋ผ "๊ฐ๋จํ๋ฉด initializer list, ๋ณต์กํ๋ฉด factory"๋ก ๋๋ ๊ณ ๋ฏผํ ํ์๊ฐ Kotlin์๋ ์๋ ์๋ค โ init ํ๋๋ก ๊ฐ๋จํ ๊ฒ๋ ๋ณต์กํ ๊ฒ๋ ๋ค ์ฒ๋ฆฌ๋๋ค.
ํ๋์ ์ ๋ฆฌ
ํ๊ณ ์ถ์ ๊ฒ | Kotlin | Dart |
๊ธฐ๋ณธ ์์ฑ | ํด๋์ค ๊ดํธ ์์ฒด๊ฐ ์์ฑ์ |
|
์ด๋ฆ ๋ถ์ฌ์ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ผ๋ก ์์ฑ | ์ธ์ด ์ง์ ์์ โ |
|
์์ฑ ์ ๊ณ์ฐ/๋ก์ง ์ฒ๋ฆฌ |
| initializer list (ํํ์ ํ๋๋ง) ๋๋ |
์ง์ง ์์ฑ์๋ฅผ ๋ชป ์ฐ๊ฒ ๋ง๊ธฐ |
| ์ด๋ฆ ์์ |
Kotlin์ "์์ฑ์๋ ํ๋, ๋๋จธ์ง๋ ๋ค companion object์ ํจ์"๋ผ๋ ๋จ์ํ ์์น์ผ๋ก ๋ฐ๊ณ , Dart๋ "์์ฑ์ ์์ฒด๋ฅผ ์ฌ๋ฌ ๊ฐ, ํ์ํ๋ฉด ํจ์์ฒ๋ผ ์์ ๋ก์ด ๊ฒ(factory)๋" ํ์ฉํ๋ ์ชฝ์ผ๋ก ๋ฌธ๋ฒ์ ์ธ๋ถํํ๋ค. ํธ์ถํ๋ ์ชฝ ์ฝ๋(ClassName.์ด๋ฆ(...))๋ ๋ ๋ค ๋น์ทํด ๋ณด์ด์ง๋ง, ๋ด๋ถ ๊ตฌํ ๋ฐฉ์์ ์์ ๋๊ฐ Dart ์ชฝ์ด ์กฐ๊ธ ๋ ๋๋์ด ์๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
์ ๋ฆฌ
- Dart๋ ์ด๋ฆ ์๋ ์์ฑ์๋ฅผ ํด๋์ค๋น ํ๋๋ง ํ์ฉํ๋ค โ ํ๋ผ๋ฏธํฐ ๊ฐ์๊ฐ ๋ฌ๋ผ๋ ์ค๋ฒ๋ก๋ฉ์ด ์ ๋๋ค
- ์ฌ๋ฌ ๋ฐฉ์์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ์ถ์ผ๋ฉด
ClassName.์ด๋ฆ(...)ํํ์ named constructor๋ฅผ ์ด๋ค - named constructor์ initializer list(
:๋ค)๋ ํจ์ ๋ชธํต์ด ์๋๋ผ ๊ฐ ๋์ ์ ์ฉ ์ฌ๋กฏ์ด๊ณ , ํํ์ ํ๋๋ง ๊ฐ๋ฅํ๋ค - ๊ฒ์ฆ, ๋ณํ, ๋ถ๊ธฐ์ฒ๋ผ ๋ณต์กํ ๋ก์ง์ด ํ์ํ๋ฉด
factory์์ฑ์๋ฅผ ์ด๋ค โ ์ค์ ๋ก ๊ฐ์ ์ฑ์ฐ๋ ์์ฑ์๋ ๋ณดํต_๋ก ์จ๊ธฐ๊ณ , factory๋ ๊ทธ๋ฆฌ๋ก ๋ค์ด๊ฐ๋ ์ฐฝ๊ตฌ ์ญํ ๋ง ํ๋ค - Kotlin์ ์ด๋ฐ named/factory ๋ฌธ๋ฒ์ด ์์ด์,
companion object์ ํ๋ฒํ ํจ์๋init๋ธ๋ก์ผ๋ก ๊ฐ์ ๋ชฉ์ ์ ์ด๋ฃฌ๋ค โ ๋์ Kotlin์init์ Dart์ initializer list๋ณด๋ค ํจ์ฌ ์์ ๋กญ๋ค
๋ค์ ๊ธ์์๋ ์์๊ณผ mixin์ ๋ค๋ค๋ณด๊ฒ ๋ค.
