{"id":332356,"date":"2023-03-13T06:26:21","date_gmt":"2023-03-13T05:26:21","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=fleet&#038;p=332356"},"modified":"2023-03-13T06:26:25","modified_gmt":"2023-03-13T05:26:25","slug":"fleet-below-deck-part-vi-ui-with-noria","status":"publish","type":"fleet","link":"https:\/\/blog.jetbrains.com\/ko\/fleet\/2023\/03\/fleet-below-deck-part-vi-ui-with-noria\/","title":{"rendered":"Fleet\uc758 \ub0b4\ubd80 \uad6c\uc870, \ud30c\ud2b8 VI \u2013 UI\uc640 Noria"},"content":{"rendered":"<p>JetBrains\uc758 \ucc28\uc138\ub300 IDE\uc778 Fleet \ube4c\ub4dc\uc5d0 \ub300\ud574 \uc54c\uc544\ubcf4\ub294 \uc5f0\uc7ac \uac8c\uc2dc\ubb3c\uc785\ub2c8\ub2e4.<\/p>\n<ul>\n<li>\ud30c\ud2b8 I \u2013 <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/01\/fleet-below-deck-part-i-architecture-overview\/\">\uc544\ud0a4\ud14d\ucc98 \uac1c\uc694<\/a><\/li>\n<li>\ud30c\ud2b8 II \u2013 <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/02\/fleet-below-deck-part-ii-breaking-down-the-editor\/\">\uc5d0\ub514\ud130 \ud574\ubd80\ud558\uae30<\/a><\/li>\n<li>\ud30c\ud2b8 III \u2013 <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/06\/fleet-below-deck-part-iii-state-management\/\">\uc0c1\ud0dc \uad00\ub9ac<\/a><\/li>\n<li>\ud30c\ud2b8 IV \u2013 <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/06\/fleet-below-deck-part-iv-distributed-transactions\/\">\ubd84\uc0b0\ud615 \ud2b8\ub79c\uc7ad\uc158<\/a><\/li>\n<li>\ud30c\ud2b8 V \u2013 <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/08\/fleet-below-deck-part-v-the-story-of-code-completion\/\">\ucf54\ub4dc \uc644\uc131 \uc774\uc57c\uae30<\/a><\/li>\n<li>\ud30c\ud2b8 VI \u2013 UI\uc640 Noria<\/li>\n<\/ul>\n<p>\uc774 \uc2dc\ub9ac\uc988\uc758 <a href=\"https:\/\/blog.jetbrains.com\/fleet\/2022\/08\/fleet-below-deck-part-v-the-story-of-code-completion\/\">\ud30c\ud2b8 V<\/a>\uc5d0\uc11c\ub294 Fleet\uc758 \uc11c\ube44\uc2a4 \uc911 \ud558\ub098\uc778 \ucf54\ub4dc \uc644\uc131\uc5d0 \ub300\ud574 \uc124\uba85\ub4dc\ub838\uc2b5\ub2c8\ub2e4. \uc774\uc81c JVM\uc744 \uc704\ud55c \uace0\uc720\ud55c \uc120\uc5b8\uc801 UI \ud504\ub808\uc784\uc6cc\ud06c\uc778 Noria\uc5d0 \ub300\ud574 \uc54c\ub824 \ub4dc\ub9b4 \uc2dc\uac04\uc785\ub2c8\ub2e4. Fleet\uc740 Noria\ub85c \ube4c\ub4dc\ub418\uc5c8\uc2b5\ub2c8\ub2e4. Noria\uc758 \uae30\ubc18\uc774 \ub418\ub294 \uc544\uc774\ub514\uc5b4, \uc8fc\uc694 \uac1c\ub150 \ubc0f \uae30\ud0c0 \uba4b\uc9c4 \uae30\ub2a5\uc744 \uc0b4\ud3b4\ubcf4\uc138\uc694.<\/p>\n<h2>\ubaa8\ub4e0 \uac83\uc774 \uc2dc\uc791\ub418\ub294 \uacf3: Noria \ucc3d<\/h2>\n<p>UI\ub294 \uc5b4\ub5bb\uac8c \ube4c\ub4dc\ub418\ub098\uc694? \uc6b0\uc120 \ub2e4\ub4e4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc0c1\ud0dc\ub97c \ub098\ud0c0\ub0bc \uc218 \uc788\uace0 UI\ub97c GUI\ub85c \ub9cc\ub4dc\ub294 \uc5ed\ud560\ub3c4 \ud558\ub294 \uadf8\ub798\ud53d \uae30\ub2a5\uc744 \uac16\ucd98 \ub514\uc2a4\ud50c\ub808\uc774\uac00 \uc788\uc744 \uac81\ub2c8\ub2e4. \uba85\ub839\uc744 \uc804\ub2ec\ud558\uace0 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ub3d9\uc791\uc744 \uc81c\uc5b4\ud558\uae30 \uc704\ud55c \ud0a4\ubcf4\ub4dc, \ub9c8\uc6b0\uc2a4 \ub610\ub294 \ud130\uce58\ud328\ub4dc \ub4f1 \ud558\ub098 \uc774\uc0c1\uc758 \uc785\ub825 \uae30\uae30\uac00 \uc788\uc744 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \ud658\uacbd\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc740 \uc0ac\uc2e4\uc0c1 \uc0ac\uc6a9\uc790 \ubc0f \uae30\ud0c0 \ucef4\ud4e8\ud130 \uc2dc\uc2a4\ud15c \uad6c\uc131 \uc694\uc18c(\ud0c0\uc774\uba38, \ud30c\uc77c \uc2dc\uc2a4\ud15c, \ub124\ud2b8\uc6cc\ud06c \ub4f1)\uac00 \uc2dc\uc791\ud55c \uc774\ubca4\ud2b8\uc5d0 \ubc18\uc751\ud558\ub294 \uc774\ubca4\ud2b8 \ub8e8\ud504\uc785\ub2c8\ub2e4. \uae30\ubcf8\uc801\uc73c\ub85c \ubc18\uc751\uc740 \ud654\uba74\uc5d0 \ud45c\uc2dc\ub418\ub294 \ub0b4\uc6a9\uc758 \uac00\uc2dc\uc801 \ubcc0\ud654\uc785\ub2c8\ub2e4.<\/p>\n<p>\uc774\ubca4\ud2b8 \ub8e8\ud504\ub77c\ub294 \ud2b9\uc9d5 \uc678\uc5d0 GUI \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc740 \uc77c\ubc18\uc801\uc73c\ub85c \uc77c\uc885\uc758 \ucc3d\uacfc \ub2f4\ub2f9\ud558\ub294 \ud654\uba74 \uc601\uc5ed, \uadf8\ub9ac\uace0 \ud574\ub2f9 \uc601\uc5ed\uc5d0\uc11c \uadf8\ub9ac\uae30 \uae30\ub2a5\uc744 \uac16\uc2b5\ub2c8\ub2e4. \ucc3d\uc740 \ubcf4\ud1b5 \uae30\ubcf8 \uc6b4\uc601 \uccb4\uc81c \ub610\ub294 \uadf8\ub97c \uae30\ubc18\uc73c\ub85c \ud55c \ucc3d \uad00\ub9ac\uc790\uc5d0 \uc758\ud574 \uc81c\uacf5\ub429\ub2c8\ub2e4. \uc6b4\uc601 \uccb4\uc81c\ub294 \uadf8\ub798\ud53d API\ub97c \uc81c\uacf5\ud558\uac70\ub098 \uadf8\ub9ac\uae30 \uae30\ub2a5\uc744 \uadf8\ub798\ud53d \ud504\ub808\uc784\uc6cc\ud06c\uc5d0 \uc704\uc784\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>Fleet\uc740 GUI \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774\uba74\uc11c JVM \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc785\ub2c8\ub2e4. Windows, macOS \ubc0f Linux\ub97c \ud3ec\ud568\ud55c \ubaa8\ub4e0 \uc8fc\uc694 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc2e4\ud589\ub429\ub2c8\ub2e4. Fleet\uc740 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \ucc3d\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 Java AWT\/Swing \ud504\ub808\uc784\uc6cc\ud06c\uc5d0 \uc758\uc874\ud558\uc9c0\ub9cc, GUI \uad6c\uc131 \uc694\uc18c\ub97c \uad00\ub9ac\ud558\uae30 \uc704\ud574 \ud574\ub2f9 \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uae30\ubc18\uc73c\ub85c \ud55c \ud558\ub098\uc758 JFrame \ubc0f JPanel\uc744 \uc0ac\uc6a9\ud560 \ubfd0, Java \ud50c\ub7ab\ud3fc\uc744 \uc0ac\uc6a9\ud558\uc9c0\ub294 \uc54a\uc2b5\ub2c8\ub2e4. Fleet\uc740 JVM\uc758 \ud654\uba74 \uadf8\ub9ac\uae30 \uae30\ub2a5\ub3c4 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \ub300\uc2e0 JetBrains\uac00 \uac1c\ubc1c\ud558\ub294 <a href=\"https:\/\/github.com\/JetBrains\/skiko\" target=\"_blank\" rel=\"noopener\">skiko-awt<\/a> \ubc14\uc778\ub529 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \ud1b5\ud574 JVM \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub124\uc774\ud2f0\ube0c 2D \uadf8\ub798\ud53d \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 <a href=\"https:\/\/skia.org\/\" target=\"_blank\" rel=\"noopener\">Skia<\/a>\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc740 \uc55e\uc11c \uc54c\ub824 \ub4dc\ub9b0 \ud504\ub808\uc784\uc6cc\ud06c\uc640 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc758 \uc870\ud569\uc744 \ubcf4\uc5ec\uc8fc\uba70, \uc774 \uc870\ud569\uc73c\ub85c \uc790\uccb4 \uc81c\uc791\ub41c UI \ud504\ub808\uc784\uc6cc\ud06c\uc778 Noria \ucc3d\uc5d0 \uc758\ud574 \uc644\ubcbd\ud788 \uad00\ub9ac\ub418\ub294 \ud654\uba74 \uc601\uc5ed\uc774 \uc0dd\uc131\ub429\ub2c8\ub2e4.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-324460\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/image-54.png\" alt=\"\" width=\"966\" height=\"456\"><\/figure>\n<p>Fleet \ucc3d\uc5d0 \ud45c\uc2dc\ub418\ub294 \ubaa8\ub4e0 \ud56d\ubaa9\uc740 Noria \uad6c\uc131 \uc694\uc18c\uc785\ub2c8\ub2e4. \ud328\ub110, \ud0ed, \ubc84\ud2bc, \ud234\ud301, \ud14d\uc2a4\ud2b8 \uc5d0\ub514\ud130, \ud130\ubbf8\ub110, diff \ubdf0 \ubc0f docker \ubdf0\ub294 Noria\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\uba70 Noria\uc758 \uc774\ubca4\ud2b8 \ub8e8\ud504 \ubc18\uc751 \uacb0\uacfc\uc5d0 \ub530\ub77c \uc9c0\uc18d\uc801\uc73c\ub85c \ubcc0\uacbd\ub429\ub2c8\ub2e4.<\/p>\n<p>&#8220;Noria\uc5ec\uc57c \ud558\ub294 \uc774\uc720\uac00 \ubb54\uac00\uc694?&#8221;\ub77c\uace0 \uc9c8\ubb38\ud558\uc2e4 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc774\ubbf8 \ud6cc\ub96d\ud55c UI \ud504\ub808\uc784\uc6cc\ud06c\ub294 \ub108\ubb34\ub098 \ub9ce\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \ud504\ub808\uc784\uc6cc\ud06c\ub294 \ubaa8\ub4e0 \uc8fc\uc694 \ub370\uc2a4\ud06c\ud1b1 \ud50c\ub7ab\ud3fc\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uace0, \uc774\ub97c \uc774\uc6a9\ud574 \uc138\ub828\ub41c \ub514\uc790\uc778\uc5d0 \ubc18\uc751 \uc18d\ub3c4\uac00 \ub9e4\uc6b0 \uc6b0\uc218\ud55c GUI \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ubc14\ub85c \ub9cc\ub4e4 \uc218 \uc788\ub294\ub370 \uc0c8 UI \ud504\ub808\uc784\uc6cc\ud06c\ub97c \ub9cc\ub4e4\uc5b4\ub0b4\uc57c \ud588\ub358 \uc774\uc720\ub294 \ubb34\uc5c7\uc77c\uae4c\uc694? \uc774\uc720\ub294 \uc0c1\ud669\uc774 \ub2ec\ub790\uae30 \ub54c\ubb38\uc785\ub2c8\ub2e4. \uc9c0\uae08\ubd80\ud130 \uae30\uc874 UI \ud504\ub808\uc784\uc6cc\ud06c\uc758 \uc5ed\uc0ac\ub97c \uc54c\uc544\ubcf4\uace0, Fleet\uc73c\ub85c \ud0c4\uc0dd\ud55c \uc81c\ud488\uc744 \uac1c\ubc1c\ud558\uae30 \uc2dc\uc791\ud588\uc744 \ub54c \uadf8\ub7ec\ud55c \uc120\ud0dd\uc9c0\uac00 \uc788\uc5c8\ub294\uc9c0 \uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>UI \uc811\uadfc \ubc29\uc2dd\uc758 \uac04\ub7b5\ud55c \uc5ed\uc0ac<\/h2>\n<p>GUI \ud504\ub808\uc784\uc6cc\ud06c(GUI \uc790\uccb4\uac00 \uc544\ub2d8)\uc5d0 \ub300\ud55c \uc544\uc774\ub514\uc5b4\uc640 \uc811\uadfc \ubc29\uc2dd\uc740 Alan Kay\ub97c \ube44\ub86f\ud55c Xerox PARC\uc758 \uc5f0\uad6c\uc790 \ud300\uc774 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Smalltalk\" target=\"_blank\" rel=\"noopener\">Smalltalk \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4<\/a>\uc6a9 \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uac1c\ubc1c\ud55c 70\ub144\ub300\ub85c \uac70\uc2ac\ub7ec \uc62c\ub77c\uac11\ub2c8\ub2e4. UI \ud504\ub808\uc784\uc6cc\ud06c \ucd08\uae30\ubd80\ud130 \uac1c\ubc1c\uc790\ub4e4\uc740 \uc544\ud0a4\ud14d\ucc98 \ubb38\uc81c\uc5d0 \uba85\ud655\ud788 \ucd08\uc810\uc744 \ub9de\ucdc4\uc2b5\ub2c8\ub2e4. \uc608\uce21\ud560 \uc218 \uc5c6\ub294 \uc0ac\uc6a9\uc790\uc758 \ud589\uc704\uc640 \uadf8\uc5d0 \ub530\ub978 UI \ubc18\uc751\uc744 \uace0\ub824\ud558\uace0, \uc544\ud0a4\ud14d\ucc98 \uba74\uc5d0\uc11c \uc5c9\ub9dd\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ub098\uc624\ub294 \uac83\uc744 \ubc29\uc9c0\ud558\uba74\uc11c, \ud654\uba74\uc5d0 \uc5ec\ub7ec UI \uad6c\uc131 \uc694\uc18c\uac00 \uc788\ub294 \uc774\ubca4\ud2b8 \ub8e8\ud504\uc0c1\uc5d0 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\uc131\ud558\uae30\ub780 \uc26c\uc6b4 \uc77c\uc774 \uc544\ub2c8\uc5c8\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uc811\uadfc \ubc29\uc2dd\uc744 \uc790\uc138\ud788 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud55c \uac00\uc9c0 \uc608\ub294 <a href=\"https:\/\/folk.universitetetioslo.no\/trygver\/themes\/mvc\/mvc-index.html\" target=\"_blank\" rel=\"noopener\">Trygve M. H. Reenskaug<\/a>\uc758 \uba54\ubaa8\uc785\ub2c8\ub2e4. \uc5ec\uae30\uc11c Trygve\ub294 GUI \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \uad6c\uc870\ub97c \uc81c\uacf5\ud558\ub294 \uc77c\ub828\uc758 \uc544\uc774\ub514\uc5b4\uc778, \uc8fc\ubaa9\ud560 \ub9cc\ud55c Model-View-Controller \uc544\ud0a4\ud14d\ucc98 \uc2a4\ud0c0\uc77c, MVC\uc758 \uc778\uc149\uc158\uc5d0 \ub300\ud574 \uacf0\uacf0\uc774 \uac80\ud1a0\ud569\ub2c8\ub2e4.<\/p>\n<p>MVC \uc2a4\ud0c0\uc77c\uc744 \uc801\uc6a9\ud558\ub294 \uba85\ud655\ud55c \ubc29\ubc95\uc774 \uc5c6\uc5c8\uc73c\ubbc0\ub85c, \ub2e4\ub978 \uc6a9\uc5b4(\uc608: MVP \u2013 Model-View-Presenter)\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ub97c \uc7ac\uad6c\uc131\ud558\ub824\ub294 \uc218\ub9ce\uc740 \uc2dc\ub3c4\uac00 \uc788\uc5c8\uc2b5\ub2c8\ub2e4. \uc774\ub97c \uc9c0\uc6d0\ud55c\ub2e4\ub358 UI \ud504\ub808\uc784\uc6cc\ud06c\ub294 \uc800\ub9c8\ub2e4 \ud2b9\uc815\ud55c \uad6c\ud604 \ubc29\ubc95\uc744 \uc81c\uacf5\ud588\uace0, \ub2e4\uc74c\uacfc \uac19\uc740 \uba87 \uac00\uc9c0 \uc77c\ubc18\uc801\uc778 \uc0ac\ud56d \uc678\uc5d0\ub294 \uc11c\ub85c \uacf5\ud1b5\uc810\uc774 \ub9ce\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n<ul>\n<li>\ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc758 \uac1d\uccb4 \uc9c0\ud5a5 \uae30\ub2a5\uc5d0 \uc758\uc874.<\/li>\n<li>\ud504\ub808\uc820\ud14c\uc774\uc158\uc5d0\uc11c \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1 \ubd84\ub9ac(\uc548\ud0c0\uae5d\uac8c\ub3c4 \ubd84\ub9ac\ud55c \ud6c4\uc5d0 \ud504\ub808\uc820\ud14c\uc774\uc158\uc5d0 \ub610 \ud2b9\uc815 \ub85c\uc9c1\uc774 \ud544\uc694\ud560 \uc218 \uc788\uc74c).<\/li>\n<li><a href=\"https:\/\/en.wikipedia.org\/wiki\/Observer_pattern\" target=\"_blank\" rel=\"noopener\">\uc635\uc11c\ubc84 \ud328\ud134<\/a>\uc744 \ud1b5\ud574 \ubcc0\uacbd \uc0ac\ud56d \uad00\ucc30(\uc774 \ud328\ud134\uc744 \uacfc\ud558\uac8c \uc774\uc6a9\ud558\ub294 \uc18c\uc2a4\ub97c \uc77d\uc73c\uba74 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc9c4\ud589\ub418\uace0 \uc788\ub294 \uc0ac\ud56d\uc744 \ud30c\uc545\ud558\uae30\uac00 \ub108\ubb34 \uc5b4\ub824\uc6cc\uc838 \uad00\ub828 \ucf54\ub4dc\uc5d0\uc11c \uac00\ub3c5\uc131 \ubb38\uc81c \ubc1c\uc0dd).<\/li>\n<\/ul>\n<p>\ub610 \ub2e4\ub978 \uac1c\ubc1c\uc758 \ubc29\ud5a5\ub3c4 \uc788\uc5c8\uc2b5\ub2c8\ub2e4. \uc544\ud0a4\ud14d\ucc98\ub97c <em>\uc591\uc2dd<\/em>\uc73c\ub85c \uad6c\uc870\ud654\ud558\uc5ec \ub2e8\uc21c\ud654\ud558\uace0, \uc591\uc2dd\uc5d0 \uc77c\ub828\uc758 <em>\uc81c\uc5b4 \uae30\ub2a5<\/em>\uc744 \uc801\uc6a9\ud558\uba70, \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0c1\ud0dc\ub97c \uc591\uc2dd\uc758 \uad6c\uc131 \uc694\uc18c\uc5d0 \uc5f0\uacb0\ud558\ub294 \ub85c\uc9c1\uc744 \uc0ac\uc6a9\ud558\ub824\ub294 \uc2dc\ub3c4\uc600\uc2b5\ub2c8\ub2e4. 1990\ub144\ub300\uc5d0 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Delphi_(software)\" target=\"_blank\" rel=\"noopener\">Borland Delphi<\/a> \ubc0f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Visual_Basic_(classic)\" target=\"_blank\" rel=\"noopener\">Visual Basic<\/a>\uc774 \ub300\uc911\ud654\ud55c \uc774 \uc544\uc774\ub514\uc5b4\ub97c \ud1b5\ud574 Button1Click \uc138\ub300\uc758 \uac1c\ubc1c\uc790\ub294 \uc544\ud0a4\ud14d\ucc98\uc5d0 \ub300\ud574 \uc0dd\uac01\ud558\uc9c0 \uc54a\uace0 \ud3b8\ud558\uac8c \ub300\uaddc\ubaa8 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud560 \uc218 \uc788\uc5c8\uc2b5\ub2c8\ub2e4. \uac1d\uccb4 \uc9c0\ud5a5 \uc131\ud5a5\uc758 \uc5f0\uad6c\uc790\uc640 \uc2e4\ubb34\uc790\ub294 \uc774 \uc811\uadfc \ubc29\uc2dd\uc744 \uc904\uace7 \ube44\ud310\ud588\uc9c0\ub9cc, \uc194\uc9c1\ud788 \uc544\ud0a4\ud14d\ucc98\uac00 \uc5c6\ub4e0, \uc544\ud0a4\ud14d\ucc98 \uc9c0\uce68\uc774 \uc5c4\uaca9\ud558\ub4e0, \uc591\ucabd\uc5d0\uc11c \ubc1c\uc0dd\ub418\ub294 \ud070 \ud63c\ub780\uc744 \ubcf4\uba74 \uc5b4\ub290 \uac83\uc774 \ub0ab\ub2e4\uace0 \ud558\uae30\uac00 \uc5b4\ub824\uc6b8 \ub54c\uac00 \ub9ce\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n<p>Martin Fowler\ub294 \uc790\uc2e0\uc758 \uc800\uc11c(\uc548\ud0c0\uae5d\uac8c\ub3c4 \ubbf8\uc644\uc131), <a href=\"https:\/\/www.martinfowler.com\/eaaDev\/\" target=\"_blank\" rel=\"noopener\"><em>Further Patterns of Enterprise Application Architecture(\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc544\ud0a4\ud14d\ucc98\uc758 \ud328\ud134 \ud0d0\uad6c)<\/em><\/a>\uc758 <a href=\"https:\/\/www.martinfowler.com\/eaaDev\/uiArchs.html\" target=\"_blank\" rel=\"noopener\">\ud1b5\ucc30\ub825\uc774 \ube5b\ub098\ub294 \ubd80\ubd84(\ubc1c\ucdcc)<\/a>\uc5d0\uc11c UI \ud504\ub808\uc784\uc6cc\ud06c \uac1c\ubc1c\uc5d0 \ub300\ud55c \uc774 \ub450 \uac00\uc9c0 \ubc29\ud5a5\uc744 \uc0b4\ud3b4\ubcf4\uc558\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ud55c\ud3b8, \ub2f9\uc2dc\uc5d0\ub294 <a href=\"https:\/\/en.wikipedia.org\/wiki\/PHP\" target=\"_blank\" rel=\"noopener\">PHP<\/a>\ub3c4 \uc788\uc5c8\uc2b5\ub2c8\ub2e4. 90\ub144\ub300 \uc911\ubc18\uc5d0 \uc2dc\uc791\ub41c PHP\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\uba74 \ubb34\ucc99 \ud3b8\ub9ac\ud588\uc2b5\ub2c8\ub2e4. \uc2dc\uc791\ud558\uae30\uac00 \ub108\ubb34\ub098 \uc26c\uc6e0\uc73c\uba70, \ud504\ub85c\ub355\uc158\uc73c\ub85c \ubc14\ub85c \uc2e4\ud589\ud560 \uc218 \uc788\uc5c8\uc2b5\ub2c8\ub2e4. PHP\ub294 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Template_processor\" target=\"_blank\" rel=\"noopener\">\ud15c\ud50c\ub9bf \ucc98\ub9ac<\/a>\ub97c \ub300\uc911\ud654\ud588\uc2b5\ub2c8\ub2e4. \ud558\ub098\uc758 \ucf54\ub4dc\uc5d0 \ub85c\uc9c1(\ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4 \uc9c0\uce68)\uacfc \ud504\ub808\uc820\ud14c\uc774\uc158(HTML \ud0dc\uadf8)\uc744 \ud63c\ud569\ud558\ub294 \uc811\uadfc \ubc29\uc2dd\uc73c\ub85c, MVC \uc21c\uc218\uc8fc\uc758\uc790\uc758 \ub208\uc5d0\ub294 \ub054\ucc0d\ud55c \ubc94\uc8c4\uc600\uc2b5\ub2c8\ub2e4. \uc5b4\ub5a4 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\ub3c4 \uac1c\ubc1c\uc790\ub4e4\ub85c\ubd80\ud130 \uc774\ub807\uac8c \ub9ce\uc740 \ubc18\ubc1c\uc744 \ubc1b\uc740 \uc801\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. &#8216;PHP hate&#8217;\ub97c \uad6c\uae00\uc5d0\uc11c \uac80\uc0c9\ud574\ubcf4\uae30\ub9cc \ud574\ub3c4 \uc5b4\ub560\ub294\uc9c0 \uc798 \uc54c \uc218 \uc788\uc2b5\ub2c8\ub2e4. &#8216;\uae54\ub054\ud55c \ucf54\ub4dc \ucc9c\uad6d\uc758 \uc218\ud638\uc790\ub4e4&#8217;\uc740 \uc5ec\uc804\ud788 \uc774\ub7ec\ud55c \uc774\uc720\ub85c PHP\ub97c \uc2eb\uc5b4\ud569\ub2c8\ub2e4(\ub610\ud55c PHP\uac00 \uc18c\ud504\ud2b8\uc6e8\uc5b4\ub97c \uac1c\ubc1c\ud558\ub294 \uc720\uc77c\ud55c &#8216;\uc62c\ubc14\ub978 \ubc29\ubc95&#8217;\uc744 \ubaa8\ub974\uace0 \uc790\ub780 \ub9ce\uc740 \uc2e0\uc785 \uac1c\ubc1c\uc790\ub97c \uc5c5\uacc4\uc5d0 \ub4e4\uc5ec\ub193\uc558\uae30 \ub54c\ubb38\uc77c \uc218 \uc788\uc2b5\ub2c8\ub2e4).<\/p>\n<p>\ud558\uc9c0\ub9cc \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0 \ub300\ud574 \ud310\ub2e8\ud558\uc9c0 \ub9d0\uace0 \uc774 \uc0c8\ub85c\uc6b4 \uc544\uc774\ub514\uc5b4\uac00 \ubb34\uc5c7\uc774\uba70 \uc5b4\ub5a0\ud55c \ubc29\ud5a5\uc73c\ub85c \ubc1c\uc804\ud558\uac8c \ub420\uc9c0\ub97c \uc815\ud655\ud788 \ubcf4\uba74 \uc88b\uaca0\uc2b5\ub2c8\ub2e4. \ub370\uc774\ud130\ub97c \ubcf4\ub294 \ubc29\uc2dd\uc740 \ub370\uc774\ud130\ub97c \uc870\uc791\ud558\ub294 \ubc29\uc2dd\uacfc \ubc00\uc811\ud558\uac8c \uad00\ub828\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4. PHP\ub97c \uc0ac\uc6a9\ud558\uba74 \ub354 \uc774\uc0c1 \ub85c\uc9c1\uacfc \ud504\ub808\uc820\ud14c\uc774\uc158\uc744 \uad6c\ubd84\ud560 \ud544\uc694\uac00 \uc5c6\uc2b5\ub2c8\ub2e4. \uacb0\uad6d \ub300\ubd80\ubd84\uc758 \ub85c\uc9c1\uc740 \ud504\ub808\uc820\ud14c\uc774\uc158\uc5d0 \uc788\uc2b5\ub2c8\ub2e4. \ud504\ub808\uc820\ud14c\uc774\uc158\uc744 \uc870\uc791\ud558\ub294 \uc8fc\uccb4\ub294 \ubcf4\uac70\ub098 \uc190\ub308 \uc218 \uc5c6\ub294 \ucd94\uc0c1 \ub370\uc774\ud130\uac00 \uc544\ub2c8\ub77c \uc0ac\uc6a9\uc790\uc774\uae30 \ub54c\ubb38\uc785\ub2c8\ub2e4. PHP\ub294 \uace0\uc720\ud55c \ub514\uc790\uc778, \uc0ac\uc6a9\uc790\uc758 \ud589\uc704\uc5d0 \ub300\ud55c \ubc18\uc751 \ubc0f \uae30\ud0c0 \ub3d9\uc791\uc774 \uc788\ub294 \ud65c\uc131 \uc5d4\ud2f0\ud2f0\uc778 <em>\uad6c\uc131 \uc694\uc18c<\/em>\uac00 \ud544\uc694\ud568\uc744 \ubd84\uba85\ud788 \ubcf4\uc5ec\uc8fc\uc5c8\uc2b5\ub2c8\ub2e4. \uad6c\uc131 \uc694\uc18c\ub294 \ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\ub85c \uad6c\uc131\ub420 \uc218 \uc788\uc73c\uba70, \uc77c\ubd80 \uacf5\uc720 \uc0c1\ud0dc\ub97c \ud1b5\ud574 \uc778\uc811 \uad6c\uc131 \uc694\uc18c\uc640 \ud6a8\uacfc\uc801\uc73c\ub85c \uc0c1\ud638\uc791\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4, \ud55c \uad6c\uc131 \uc694\uc18c\uc758 \ud56d\ubaa9 \ubaa9\ub85d\uc740 \uccab \ubc88\uc9f8 \uad6c\uc131 \uc694\uc18c\uc5d0\uc11c \uc120\ud0dd\ub41c \ud56d\ubaa9\uc5d0 \ub530\ub77c \ub0b4\uc6a9\uc774 \ub2ec\ub77c\uc9c0\ub294 \ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\ub85c \ubcc0\uacbd \uc2dc\uadf8\ub110\uc744 \uc804\ub2ec\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Ajax_(programming)\" target=\"_blank\" rel=\"noopener\">Ajax(\ube44\ub3d9\uae30 JavaScript \ubc0f XML)<\/a>\ub294 \uc6f9 \uad6c\uc131 \uc694\uc18c\ub97c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc8fc\uc694 \ube4c\ub4dc\uc6a9 \ube14\ub85d\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \uc774 \uc544\uc774\ub514\uc5b4\ub97c \ub354\uc6b1 \ubc1c\uc804\uc2dc\ucf30\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uc6f9 \uad6c\uc131 \uc694\uc18c\ub294 \ubc31\uc5d4\ub4dc \ubc0f \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ub85c\uc9c1\uc744 \uacb0\ud569\ud558\uace0, \uc774\ub97c \ud504\ub808\uc820\ud14c\uc774\uc158\uacfc \ud63c\ud569\ud588\uc2b5\ub2c8\ub2e4. \uc88b\ub4e0 \ub098\uc058\ub4e0 \uc774 \uc544\uc774\ub514\uc5b4\ub294 \ud604\uc7ac\uc758 \uc6f9 \ubc0f \uc6f9 \uac1c\ubc1c \ud658\uacbd\uc744 \uad6c\ud604\ud574\uc8fc\uc5c8\uc2b5\ub2c8\ub2e4.<\/p>\n<p>2010\ub144\ub300 \ucd08, <a href=\"https:\/\/en.wikipedia.org\/wiki\/React_(JavaScript_library)\" target=\"_blank\" rel=\"noopener\">React<\/a>\ub294 \uc644\uc804\ud788 \uc0c8\ub85c\uc6b4 UI \uac1c\ubc1c \uc138\uc0c1\uc744 \uc5f4\uc5c8\uc2b5\ub2c8\ub2e4. \ud504\ub7f0\ud2b8\uc5d4\ub4dc \uac1c\ubc1c\uc790 \uc0ac\uc774\uc5d0\uc11c\ub294 React \ub610\ub294 Angular \uc911 \uc5b4\ub290 \uac83\uc774 \ub354 \ub098\uc740\uc9c0, \uc5b4\ub5a4 \uc0c1\ud0dc \uad00\ub9ac\uc790\ub97c \uc0ac\uc6a9\ud574\uc57c \ud558\ub294\uc9c0\uc5d0 \ub300\ud574 \uc758\uacac\uc774 \ubd84\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, \ud65c\uc131 UI \uad6c\uc131 \uc694\uc18c \uad00\ub828 \uc544\uc774\ub514\uc5b4\uc5d0\ub294 \ud604\uc7ac \ub2e4\ub4e4 \uc775\uc219\ud574\uc9c4 \uc0c1\ud0dc\uc785\ub2c8\ub2e4. \uc2ec\uc9c0\uc5b4 \ub370\uc2a4\ud06c\ud1b1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uac1c\ubc1c\uc5d0 \uc6f9 \uae30\uc220\uc744 \uc801\uc6a9\ud558\uae30\ub3c4 \ud569\ub2c8\ub2e4(\uacb0\uacfc\ubb3c\uc774 \ud56d\uc0c1 \uc644\ubcbd\ud55c \uc751\ub2f5\uc131\uacfc \ub514\uc790\uc778\uc744 \uc81c\uacf5\ud558\uc9c0\ub294 \uc54a\uc9c0\ub9cc \ub9d0\uc774\uc8e0).<\/p>\n<p>React\uac00 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Declarative_programming\" target=\"_blank\" rel=\"noopener\">\uc120\uc5b8\uc801 \ud504\ub85c\uadf8\ub798\ubc0d<\/a> \ubc0f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reactive_programming\" target=\"_blank\" rel=\"noopener\">\ubc18\uc751\ud615 \ud504\ub85c\uadf8\ub798\ubc0d<\/a>\uc744 \ub300\uc138\ub85c \ub9cc\ub4e0 \uacf5\ub85c\ub294 \uc778\uc815\ud574\uc57c \ud569\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uae30\uc220\uc740 \uc774\uc804\uc5d0\ub294 \ube5b\uc744 \ubcf4\uc9c0 \ubabb\ud558\uc5ec \ud504\ub85c\ub355\uc158 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uac70\uc758 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uac00\uc7a5 \uc8fc\ubaa9\ud560 \ub9cc\ud55c \uc694\uc18c\uc778 UI \ud504\ub808\uc784\uc6cc\ud06c\ub97c \ud3ec\ud568\ud558\uc5ec, React\uc640 \ud568\uaed8 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc758 \ub9ce\uc740 \uc601\uc5ed\uc5d0 \ud37c\uc838 \ub098\uac14\uc2b5\ub2c8\ub2e4.<\/p>\n<p>2010\ub144\ub300 \ub9d0\uc5d0\ub294 \ubaa8\ubc14\uc77c \uc2dc\uc2a4\ud15c\uc6a9 UI \ud504\ub808\uc784\uc6cc\ud06c \uc804\ubc18\uc5d0 \ubcf4\uae09\ub41c \ub3d9\uc77c\ud55c UI \uc811\uadfc \ubc29\uc2dd\uc774 \uad00\ucc30\ub418\uae30 \uc2dc\uc791\ud588\uc2b5\ub2c8\ub2e4. \uac00\uc7a5 \ub450\ub4dc\ub7ec\uc9c4 \uc608\ub85c\ub294 Apple\uc758 SwiftUI \ubc0f Google\uc758 Jetpack Compose\uac00 \uc788\uc2b5\ub2c8\ub2e4. \uace7\uc774\uc5b4 \ub370\uc2a4\ud06c\ud1b1 \uc2dc\uc2a4\ud15c\uc6a9 UI \ud504\ub808\uc784\uc6cc\ud06c\uc5d0\uc11c\ub3c4 \ub3d9\uc77c\ud55c \ub3d9\ud5a5\uc774 \ud655\uc778\ub418\uc5c8\uc2b5\ub2c8\ub2e4. 2020\ub144\ub300 \ucd08\uc5d0\ub294 Google\uc758 Jetpack Compose\ub97c \uae30\ubc18\uc73c\ub85c JetBrains\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uba4b\uc9c4 <a href=\"https:\/\/www.jetbrains.com\/ko-kr\/lp\/compose-desktop\/\" target=\"_blank\" rel=\"noopener\">Compose for Desktop<\/a>\uc774 \ub098\uc654\uc2b5\ub2c8\ub2e4. \ud558\uc9c0\ub9cc Fleet\uc744 \uc791\uc5c5\ud558\uae30 \uc2dc\uc791\ud588\uc744 \ub54c Jetpack Compose\ub294 \uc5c6\uc5c8\uae30 \ub54c\ubb38\uc5d0 Noria\uac00 \ud0c4\uc0dd\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n<h2>\uc99d\ubd84 \uacc4\uc0b0<\/h2>\n<p>\ud765\ubbf8\ub86d\uac8c\ub3c4, Noria\uc758 \ud575\uc2ec\uc740 UI \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc544\ub2d9\ub2c8\ub2e4. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Incremental_computing\" target=\"_blank\" rel=\"noopener\">\uc99d\ubd84 \uacc4\uc0b0<\/a>\uc6a9 \ud50c\ub7ab\ud3fc\uc785\ub2c8\ub2e4. \uc0c1\ud638 \uc885\uc18d\ub41c \uad6c\uc131 \uc694\uc18c\uac00 \uc788\ub294 \uc5ec\ub7ec \ubd80\ubd84\uc73c\ub85c \uad6c\uc131\ub41c \uae34 \uc218\ud559 \uacf5\uc2dd\uc774 \uc788\ub2e4\uace0 \uac00\uc815\ud574 \ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uacf5\uc2dd\uc740 \uc2a4\ud504\ub808\ub4dc\uc2dc\ud2b8\uc640 \uc720\uc0ac\ud558\uac8c \ub54c\ub54c\ub85c \uc7ac\uacc4\uc0b0\uc774 \ud544\uc694\ud558\uac70\ub098 \uc885\uc18d\ub41c \uad6c\uc131 \uc694\uc18c\uc758 \uc7ac\uacc4\uc0b0\uc744 \ud2b8\ub9ac\uac70\ud574\uc57c \ud569\ub2c8\ub2e4. Noria\ub294 \uc774\ub7ec\ud55c \uc720\ud615\uc758 \uacf5\uc2dd\uc744 \uacc4\uc0b0\ud558\uace0 \ub2e4\uc2dc \uacc4\uc0b0\ud558\ub294 \ub370 \ud0c1\uc6d4\ud569\ub2c8\ub2e4. \uc5ec\uae30\uc11c \uae30\ubcf8 \uc6d0\uce59\uc740 \ubd88\ud544\uc694\ud55c \uacc4\uc0b0\uc744 \ud53c\ud558\uace0 \ucd5c\uc885 \uacb0\uacfc\ub97c \uc0dd\uc131\ud558\ub294 \ub370 \ud544\uc694\ud55c \ubd80\ubd84\ub9cc \ub2e4\uc2dc \uacc4\uc0b0\ud558\ub294 \uac83\uc785\ub2c8\ub2e4.<\/p>\n<p>UI\ub294 \uc5b4\ub5a8\uae4c\uc694? \uc774\uac83\ub3c4 \uadf8\ub7ec\ud55c \uc885\ub958\uc758 \uacf5\uc2dd\uc73c\ub85c \ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4. \uad6c\uc131 \uc694\uc18c \ubc0f \ud558\uc704 \uad6c\uc131 \uc694\uc18c\ub85c \uad6c\uc131\ub41c \ud2b8\ub9ac \uac19\uc740 \uad6c\uc870\uc785\ub2c8\ub2e4. \uc774\ub7ec\ud55c \uad6c\uc131 \uc694\uc18c\ub294 \ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \uc77c\ubd80\uc778 \ub3d9\uc2dc\uc5d0 \ub2e4\ub978 \uc885\uc18d\uc131\uc744 \uac00\uc9c8 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc774\ub294 \uc885\uc18d\uc131\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc131 \uc788\ub294 \ube44\uc21c\ud658 \uadf8\ub798\ud504(DAG)\ub97c \ub9cc\ub4ed\ub2c8\ub2e4. \uad6c\uc131 \uc694\uc18c \uc911 \ud558\ub098\uc758 \uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub418\uba74 \uc9c1\uac04\uc811\uc801\uc73c\ub85c \uc5ec\uae30\uc5d0 \uc885\uc18d\ub41c \ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\uacbd\ub3c4 \ud2b8\ub9ac\uac70\ub429\ub2c8\ub2e4.<\/p>\n<p>\uc77c\ubc18\uc801\uc73c\ub85c \uc99d\ubd84 \uacc4\uc0b0\uc740 \uc608\uc0c1 \uacb0\uacfc\uac00 \ubcc0\uacbd\ub418\uc9c0 \uc54a\uc744 \uac83\uc774\ub77c\uace0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0 \uc77c\ubd80 \uacc4\uc0b0 \uac74\ub108\ub6f0\uae30\ub97c \uc9c0\uc6d0\ud569\ub2c8\ub2e4. UI\uc758 \uacbd\uc6b0, \ubcc0\uacbd\uc774 \ud544\uc694\ud558\uc9c0 \uc54a\uc740 \uad6c\uc131 \uc694\uc18c\ub294 \uc190\ub300\uac70\ub098 \ub2e4\uc2dc \uadf8\ub9ac\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc774 \uac04\ub2e8\ud55c Tic-Tac-Toe \uac8c\uc784\uc5d0\uc11c \ud55c \uc218 \ub454\ub2e4\uace0 \uac00\uc815\ud574 \ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<figure class=\"wp-block-table\">\n<table>\n<tbody>\n<tr>\n<td class=\"has-text-align-center\" data-align=\"center\">\uc804<\/td>\n<td class=\"has-text-align-center\" data-align=\"center\">\ud6c4<\/td>\n<\/tr>\n<tr>\n<td class=\"has-text-align-center\" data-align=\"center\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/image-56.png\" alt=\"\" width=\"253\" height=\"250\"><\/td>\n<td class=\"has-text-align-center\" data-align=\"center\"><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/image-57.png\" alt=\"\"><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/figure>\n<p>\uc140\uc774 \uc788\ub294 \uadf8\ub9ac\ub4dc\uac00 \uc788\uc2b5\ub2c8\ub2e4. \uc624\ub978\ucabd \uc0c1\ub2e8 \ubaa8\uc11c\ub9ac\ub97c \ud074\ub9ad(X\ub97c \ucd94\uac00)\ud560 \ub54c \uc5b4\ub5a4 \uc140\uc774 \ubcc0\uacbd\ub418\uc5b4\uc57c \ud560\uae4c\uc694? \uccab \ubc88\uc9f8 \ud589\uc758 \uc140\uc774 \uc2b9\ub9ac\ud588\uc73c\ubbc0\ub85c \ud574\ub2f9 \uc140\uc744 \ub2e4\uc2dc \uadf8\ub824\uc57c \ud569\ub2c8\ub2e4. \ub2e4\ub978 \uc140\uc740 \ubcc0\uacbd\ub418\uc9c0 \uc54a\uc558\uc73c\ubbc0\ub85c, \ub2e4\uc2dc \uadf8\ub9ac\uc9c0 \uc54a\ub294 \ud3b8\uc774 \uc88b\uc2b5\ub2c8\ub2e4. \ud544\uc694\ud55c \ub85c\uc9c1\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\uc131 \uc694\uc18c \ubc0f \uacc4\uc0b0\uc744 \uad6c\uc131\ud569\ub2c8\ub2e4.<\/p>\n<ul>\n<li>2D \uadf8\ub9ac\ub4dc\ub294 \uc140\uc744 \ud3ec\ud568\ud558\uba70 \ud589, \uc5f4, \ud328\ub529 \ub4f1\uc73c\ub85c \ub808\uc774\uc544\uc6c3\uc744 \uc124\uba85\ud558\ub294 \ubc29\ubc95\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/li>\n<li>\uac01 \uc140\uc5d0\ub294 \ub0b4\uc6a9\uc5d0 \ub300\ud55c \uc815\ubcf4(X \ub610\ub294 O\uac00 \uadf8 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc5ec\ubd80) \ubc0f \uc2b9\ub9ac \ud589, \uc5f4 \ub610\ub294 \ub300\uac01\uc120\uc758 \uc77c\ubd80\uac00 \ub420 \uac00\ub2a5\uc131\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc788\uc73c\uba70 \uc774\ub7ec\ud55c X \ubc0f O\uc758 \uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub420 \ub54c \ub2e4\uc2dc \uadf8\ub9b4 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/li>\n<li>\uc624\ub978\ucabd \uc0c1\ub2e8 \uc140\uc744 \ud074\ub9ad\ud558\uba74 \ub0b4\uc6a9\uc774 \ubcc0\uacbd\ub418\uace0 \ub2e4\uc2dc \uadf8\ub9ac\uae30\uac00 \ud2b8\ub9ac\uac70\ub418\uc9c0\ub9cc, \uac8c\uc784 \uc885\ub8cc \uc5ec\ubd80 \ud655\uc778 \ubc0f \uc2b9\ub9ac \uc140\uc758 \ud574\ub2f9 \uc124\uc815 \ubcc0\uacbd\ub3c4 \ud2b8\ub9ac\uac70\ud574\uc57c \ud569\ub2c8\ub2e4.<\/li>\n<li>\uc2b9\ub9ac \uc140\uc758 \uc124\uc815\uc744 \ubcc0\uacbd\ud558\uba74 \ub178\ub780\uc0c9 \uae0b\uae30 \uc120\uc73c\ub85c \ub2e4\uc2dc \uadf8\ub9ac\uae30\uac00 \ud2b8\ub9ac\uac70\ub429\ub2c8\ub2e4.<\/li>\n<\/ul>\n<p>\ub530\ub77c\uc11c \uc0ac\uc6a9\uc790\uc758 \ud589\uc704(\uc140 \ud074\ub9ad)\uc5d0 \ub300\ud55c \ubc18\uc751\uc73c\ub85c \uadf8\ub9ac\ub4dc\uac00 \ubd80\ubd84\uc801\uc73c\ub85c \ub2e4\uc2dc \uacc4\uc0b0\ub418\uace0 \uc77c\ubd80 \uc140\uc774 \ub2e4\uc2dc \uadf8\ub824\uc9c0\uc9c0\ub9cc \ub2e4\ub978 \uc140\uc740 \uadf8\ub300\ub85c \uc720\uc9c0\ub429\ub2c8\ub2e4. Noria\ub294 \ub2e4\uc74c\uc744 \ud3ec\ud568\ud558\uc5ec \uc774\ub7ec\ud55c \ub3d9\uc791\uc744 \ucc98\ub9ac\ud558\ub294 \ub370 \ud544\uc694\ud55c \ubaa8\ub4e0 \uac83\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/p>\n<ul>\n<li>\uc774\ubca4\ud2b8 \uc804\ub2ec\uc744 \ud65c\uc131\ud654\ud558\ub294 \ud2b8\ub9ac \uad6c\uc870 \uc885\uc18d\uc131\uacfc \ud568\uaed8 \uad6c\uc131 \uc694\uc18c\uc758 \ub808\uc774\uc544\uc6c3\uc744 \ud2b8\ub9ac \uad6c\uc870\ub85c \uc124\uba85\ud558\ub294 \uc120\uc5b8\uc801 Kotlin DSL.<\/li>\n<li>\uc989\uac01\uc801 \ubc18\uc751\uc744 \uad6c\ud604\ud558\ub294 \uad6c\uc131 \uc694\uc18c\uc5d0 \ub300\ud55c onClick-hook.<\/li>\n<li>\uc778\uc811 \ub178\ub4dc\uc758 \uc7ac\uacc4\uc0b0 \ud2b8\ub9ac\uac70\ub97c \ub2f4\ub2f9\ud558\ub294 \ud2b8\ub9ac \uad6c\uc870 \uc678\ubd80\uc758 \uc885\uc18d\uc131\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud55c <code>StateCell<\/code>.<\/li>\n<\/ul>\n<p>\ub0b4\ubd80\uc801\uc73c\ub85c, Noria\ub294 \ud544\uc694\ud558\uc9c0 \uc54a\uc740 \uacbd\uc6b0 \uc7ac\uacc4\uc0b0\uc744 \ud2b8\ub9ac\uac70\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc774\ub294 \ubaa8\ub4e0 \uc99d\ubd84 \uacc4\uc0b0 \ud50c\ub7ab\ud3fc\uc758 \ud45c\uc900 \ub3d9\uc791\uc785\ub2c8\ub2e4. Noria \uc0ac\uc6a9\uc790\ub294 \uc804\uccb4 UI\ub97c \uc124\uba85\ud558\ub294 \ud568\uc218\ub97c \uc120\uc5b8\uc801 \ubc29\uc2dd\uc73c\ub85c \uc791\uc131\ud569\ub2c8\ub2e4. \uc774 \ud568\uc218\ub294 \ubb34\uc5b8\uac00\uac00 \ubc1c\uc0dd\ud560 \ub54c\ub9c8\ub2e4 \ud638\ucd9c\ub429\ub2c8\ub2e4. \uadf8\ub7ec\ub098 Noria\ub294 \uc774\uc804 \uc2e4\ud589\uc5d0\uc11c \ubcc0\uacbd\ub41c \uc0ac\ud56d\uacfc \ubcc0\uacbd\ub418\uc9c0 \uc54a\uc740 \uc0ac\ud56d\uc744 \uc815\ud655\ud788 \ud30c\uc545\ud558\uba70, \uc7ac\uacc4\uc0b0\uc774 \ud544\uc694\ud55c UI \ud2b8\ub9ac \ubd80\ubd84\uc744 \uacb0\uc815\ud569\ub2c8\ub2e4.<\/p>\n<h2>UI \uad6c\uc131 \uc694\uc18c \uc120\uc5b8<\/h2>\n<p>\uba87 \uac00\uc9c0 \ucf54\ub4dc \uc608\uc2dc\ub97c \uc0b4\ud3b4\ubcf4\uba74\uc11c Noria\ub85c \uc791\uc5c5\ud558\uba74 \uc5b4\ub5a4 \ub290\ub08c\uc774 \ub4dc\ub294\uc9c0 \ud655\uc778\ud574\ubd05\uc2dc\ub2e4.<\/p>\n<p>\uc774\uc804 \uc139\uc158\uc5d0\uc11c \uc5b8\uae09\ud55c Tic-Tac-Toe \uad6c\uc131 \uc694\uc18c\ub294 Noria\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \ub098\ud0c0\ub0bc \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">val grid = Grid(3) { state { GridCell() } }\nval gameState = state { GameState() }\n\nclickable(onClick = { grid.checkEndOfGame(gameState) }) {\n vbox {\n   grid.gridRows.forEach {\n     hbox {\n       it.forEach {\n         cell(it, gameState)\n       }\n     }\n   }\n }\n}\n<\/pre>\n<p>\uc140\uc774 \uc788\ub294 \uadf8\ub9ac\ub4dc, \ub2e4\uc74c \ucc28\ub840\uc640 \uac8c\uc784 \uc885\ub8cc \uc0c1\ud0dc\ub97c \ub2f4\ub2f9\ud558\ub294 \uac8c\uc784 \uc0c1\ud0dc\uac00 \uc788\uc2b5\ub2c8\ub2e4. \ucc98\uc74c \ub450 \uc904\uc5d0 \uc788\ub294 2\uac1c\uc758 <code>state<\/code> \ud568\uc218\ub97c \uc8fc\ubaa9\ud558\uc138\uc694. \uc774\ub7ec\ud55c \ud568\uc218\ub294 \ucd94\uac00\uc801\uc778 \uc885\uc18d\uc131 \uc0dd\uc131\uc744 \ub2f4\ub2f9\ud569\ub2c8\ub2e4. \ub0b4\uc6a9\uc744 <em>\uc5c5\ub370\uc774\ud2b8<\/em>\ud558\uba74 \ub0b4\uc6a9\uc744 <em>\uc77d\ub294<\/em> \uad6c\uc131 \uc694\uc18c\uc758 \uc7ac\uacc4\uc0b0\uc774 \ud2b8\ub9ac\uac70\ub429\ub2c8\ub2e4.<\/p>\n<p>\uac01 \uc140\uc740 \ucf58\ud150\uce20 \ub80c\ub354\ub9c1\uc744 \ub2f4\ub2f9\ud558\uace0 \uc0ac\uc6a9\uc790 \ud074\ub9ad\uc5d0 \ubc18\uc751\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">private fun UIContext.cell(gridCell: StateCell&lt;GridCell&gt;,\n                           gameState: StateCell&lt;GameState&gt;, ...) {\n val gs = gameState.read()\n val cell = gridCell.read()\n clickable(onClick = { ... }, propagate = Propagate.CONTINUE) {\n   decorate(backgroundColor = ...) {\n     layout {\n       render(Rect(Point.ZERO, Size(size, size))) {\n       ...\n       }\n     }\n   }\n }\n}\n<\/pre>\n<p>\uc0ac\uc2e4\uc0c1 <code>cell<\/code>\uc740 <code>UIContext<\/code> \ud074\ub798\uc2a4\uc758 \ud655\uc7a5 \ud568\uc218\ub85c, Noria\ub97c \ub4b7\ubc1b\uce68\ud558\ub294 \uba54\ucee4\ub2c8\uc998\uc744 \uad6c\ud604\ud569\ub2c8\ub2e4. \uc140\uc740 \uc0c1\ud0dc\ub97c \uc77d\uc73c\ubbc0\ub85c \ud574\ub2f9 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc758\uc874\uc131\uc744 \ud45c\ud604\ud569\ub2c8\ub2e4. Noria\ub294 \uc774 \uc140\uc744 \ub2e4\uc2dc \ub80c\ub354\ub9c1\ud574\uc57c \ud558\ub294\uc9c0 \uc5ec\ubd80\ub97c \uacb0\uc815\ud558\ub294 \ub3d9\uc548 \uc774 \uc885\uc18d\uc131\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<\/p>\n<p>Noria \uad6c\uc131 \uc694\uc18c\ub294 \ud234\ud301\uc774 \uc788\ub294 \ub2e4\uc74c \ud14d\uc2a4\ud2b8 \ub77c\ubca8\ucc98\ub7fc \uac04\ub2e8\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-324471\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2023\/02\/image-55.png\" alt=\"\" width=\"278\" height=\"156\"><\/figure>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"kotlin\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">withTooltip(\"Tooltip text\") {\n   uiText(\"Point on me\")\n}<\/pre>\n<p>\ub610\ud55c Fleet \uc778\uc2a4\ud134\uc2a4\uc5d0\uc11c \uc5b4\uae40\uc5c6\uc774 \ubcfc \uc218 \uc788\ub294 \ud14d\uc2a4\ud2b8 \uc5d0\ub514\ud130\ub098 \uae30\ud0c0 \ud328\ub110 \ubc0f \ucc3d\uacfc \uac19\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>Noria\ub294 \ub2e4\uc74c\uc744 \ud3ec\ud568\ud558\uc5ec \ub370\uc2a4\ud06c\ud1b1 UI \ubc0f \uae30\ud0c0 \uba85\ubc31\ud55c UI \ud504\ub808\uc784\uc6cc\ud06c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud55c \ubaa8\ub4e0 \ud544\uc218\uc801 \uad6c\uc131 \uc694\uc18c\ub97c \uc81c\uacf5\ud569\ub2c8\ub2e4.<\/p>\n<ul>\n<li>\uad6c\uc131 \uc694\uc18c \ubc30\uce58.<\/li>\n<li>\uacbd\uacc4 \uc81c\ud55c \ubc0f \uc124\uc815.<\/li>\n<li>\ud45c\uc2dc\ub418\ub294 \ubd80\ubd84 \ub80c\ub354\ub9c1 \ubc0f \uc2a4\ud06c\ub864 \uc9c0\uc6d0 \uc81c\uacf5.<\/li>\n<li>\ucd08\uc810 \uc774\ub3d9 \uc815\uc758.<\/li>\n<li>\uc624\ubc84\ub808\uc774 \uad6c\ud604(\uc608: \uc704 \uc608\uc81c\uc758 \ud234\ud301 \ub610\ub294 \uc798\ubabb\ub41c \ucf54\ub4dc \uc870\uac01 \uc606\uc758 \uc624\ub958 \uba54\uc2dc\uc9c0).<\/li>\n<\/ul>\n<p>\uc0ac\uc6a9\uc790\uac00 Fleet\uc744 \uc2e4\ud589\ud560 \ub54c\ub9c8\ub2e4 Noria \uba54\ucee4\ub2c8\uc998\uc740 \uac00\ub2a5\ud55c \ucd5c\uc0c1\uc758 UI \ud658\uacbd\uc744 \uc81c\uacf5\ud558\uae30 \uc704\ud574 \uc5f4\uc2ec\ud788 \uc791\ub3d9\ud569\ub2c8\ub2e4.<\/p>\n<h2>\uc694\uc57d<\/h2>\n<p>Fleet\uc740 JVM\uc6a9\uc73c\ub85c \uc790\uccb4 \uc81c\uc791\ub41c UI \ud504\ub808\uc784\uc6cc\ud06c\uc778 Noria\ub85c \uad6c\ud604\ub429\ub2c8\ub2e4. Noria\uc5d0\uc11c\ub294 Kotlin \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud604\ub300\uc801\uc778 \uc120\uc5b8\uc801 \ubc29\uc2dd\uc73c\ub85c UI\ub97c \uc124\uba85\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. Noria\ub294 UI \uad6c\uc131 \uc694\uc18c \uac04\uc758 \uc885\uc18d\uc131\uc744 \ud45c\ud604\ud558\uace0 \ubd88\ud544\uc694\ud55c \ub2e4\uc2dc \ub80c\ub354\ub9c1\ud558\ub294 \uac83\uc744 \ucd5c\uc18c\ud654\ud558\ub294 \uc5ed\ud560\uc744 \ud558\ub294 \uc99d\ubd84 \uacc4\uc0b0 \ucf54\uc5b4\ub97c \uae30\ubc18\uc73c\ub85c \ud569\ub2c8\ub2e4.&nbsp;<\/p>\n<p>Noria\ub294 \uacb0\ucf54 \ud601\uc2e0\uc801\uc774\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \ud604\ub300\uc801 \ub514\uc790\uc778 \uc544\uc774\ub514\uc5b4\ub9cc \uac00\uc838\uc640\uc11c UI \ud504\ub808\uc784\uc6cc\ud06c\uc5d0 \uc801\uc6a9\ud558\uace0 Kotlin \uac10\uac01\uc744 \ub354\ud560 \ubfd0\uc785\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \uc9c0\uae08\uae4c\uc9c0 \uc800\ud76c\uac00 \uae68\ub2ec\uc740 \ubc14\uc5d0 \ub530\ub974\uba74 \uace0\uc720\ud55c \uae30\ubcf8 UI \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uac1c\ubc1c\ud558\ub294 \uac83\uc740 \uc720\uc6a9\ud558\uace0 \uc2e4\uc81c\ub85c \uc5c4\uccad\ub098\uac8c \uc7ac\ubbf8\uc788\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4!<\/p>\n<p>Fleet\uc758 \ub0b4\ubd80 \uad6c\uc870 \uc2dc\ub9ac\uc988\ub294 \ub05d\ub098\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. Fleet \ub0b4\ubd80\uc5d0 \ub300\ud574 \uacf5\uc720\ud560 \uc138\ubd80 \uc815\ubcf4\uac00 \uc5ec\uc804\ud788 \ub9ce\uc774 \uc788\uc2b5\ub2c8\ub2e4. \uc0c8\ub85c\uc6b4 \uc18c\uc2dd\uc744 \uae30\ub2e4\ub824 \uc8fc\uc138\uc694!<\/p>\n<p><em>\uac8c\uc2dc\ubb3c \uc6d0\ubb38 \uc791\uc131\uc790<\/em><\/p>\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/secure.gravatar.com\/avatar\/?s=200&#038;r=g\" width=\"200\" height=\"200\" alt=\"\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":964,"featured_media":332369,"comment_status":"closed","ping_status":"closed","template":"","categories":[623],"tags":[],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/fleet\/332356"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/fleet"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/types\/fleet"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/users\/964"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/comments?post=332356"}],"version-history":[{"count":8,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/fleet\/332356\/revisions"}],"predecessor-version":[{"id":332386,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/fleet\/332356\/revisions\/332386"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/media\/332369"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/media?parent=332356"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/categories?post=332356"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/tags?post=332356"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/ko\/wp-json\/wp\/v2\/cross-post-tag?post=332356"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}