{"id":2349,"date":"2026-09-05T17:19:20","date_gmt":"2026-09-05T17:19:20","guid":{"rendered":"https:\/\/wayhope.kro.kr\/?p=2349"},"modified":"2026-09-05T17:19:20","modified_gmt":"2026-09-05T17:19:20","slug":"userdata-gamedata-%ea%b0%9c%eb%85%90%ec%9c%bc%eb%a1%9c-%ec%ba%90%ec%8b%b1-db-dto-client-model-%ed%95%9c%eb%b2%88%ec%97%90-%ea%b5%ac%ec%84%b1-%ed%92%80%ec%8a%a4%ed%83%9d-%ea%b0%9c%eb%b0%9c","status":"publish","type":"post","link":"https:\/\/wayhope.kro.kr\/?p=2349","title":{"rendered":"UserData, GameData \uac1c\ub150\uc73c\ub85c \uce90\uc2f1, DB, DTO, Client Model \ud55c\ubc88\uc5d0 \uad6c\uc131 #\ud480\uc2a4\ud0dd \uac1c\ubc1c \ud301"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">\uc11c\ubc84 \ub370\uc774\ud130 \ubaa8\ub378 \ubc0f \ud074\ub77c\uc774\uc5b8\ud2b8 \uad6c\uc870<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">\uc628\ub77c\uc778 \uac8c\uc784\uc774\ub098 \uc11c\ube44\uc2a4\ub97c \ub9cc\ub4e4 \ub54c \ub098\ub294 DB \uc124\uacc4\ubd80\ud130 \uc2dc\uc791\ud558\ub294 \ud3b8\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uac8c\uc784 \ub85c\uc9c1\ubd80\ud130 \ub9cc\ub4e4\uae30 \uc2dc\uc791\ud558\uba74 \ub098\uc911\uc5d0 \ub370\uc774\ud130 \uad6c\uc870\uac00 \uacc4\uc18d \ubc14\ub00c\uace0, \uadf8\ub54c\ub9c8\ub2e4 \uc11c\ubc84 Model\uc774\ub098 \ud074\ub77c\uc774\uc5b8\ud2b8 Model\uae4c\uc9c0 \uac19\uc774 \uc218\uc815\ud574\uc57c \ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\ub2e4. \uadf8\ub798\uc11c \ucc98\uc74c\uc5d0 ERD\ub97c \uc791\uc131\ud558\uace0 \ub370\uc774\ud130 \uad6c\uc870\ub97c \uc5b4\ub290 \uc815\ub3c4 \ud655\uc815\ud55c \ub2e4\uc74c \uad6c\ud604\uc744 \uc2dc\uc791\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uae30\ubcf8\uc801\uc778 \uac1c\ubc1c \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>ERD \uc791\uc131 -&gt; SQL \uc0dd\uc131 -&gt; DB \uad6c\uc131 -&gt; SQL \ud30c\uc2f1 -&gt; Server Model \uc0dd\uc131 -&gt; DB\/Redis Controller \uad6c\uc131 -&gt; Repository \uad6c\uc131 -&gt; Client Model \uc0dd\uc131 -&gt; MVP \uad6c\uc131<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ERD\uc640 SQL\uc744 \uae30\uc900\uc73c\ub85c Model \uc0dd\uc131<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">ERD \uc791\uc131\uc774 \ub05d\ub098\uba74 DB \uc0dd\uc131 SQL\uc744 \ub9cc\ub4e0\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 SQL\uc740 \uadf8\ub300\ub85c DB\uc5d0\uc11c \uc2e4\ud589\ud574\uc11c \ud14c\uc774\ube14\uc744 \uc0dd\uc131\ud558\uace0, \ub3d9\uc2dc\uc5d0 \ub0b4\uac00 \ub9cc\ub4e0 SQL \ud30c\uc2f1 \ud234\uc744 \uc774\uc6a9\ud574\uc11c Node.js\uc5d0\uc11c \uc0ac\uc6a9\ud560 TypeScript <code>class<\/code> \ub610\ub294 <code>interface<\/code>\ub97c \uc0dd\uc131\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\uc804\ubd80\ud130 \ubc18\ubcf5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub358 \ubc29\uc2dd\uc774\ub77c \ud504\ub85c\uc81d\ud2b8\ub97c \ub9cc\ub4e4 \ub54c\ub9c8\ub2e4 Model\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc9c0 \uc54a\uace0 \ud30c\uc2f1 \ud234\uc744 \ud1b5\ud574 \uc0dd\uc131\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\ub807\uac8c \ud558\ub294 \uc774\uc720\ub294 DB\uc640 \ucf54\ub4dc\uc758 \ub370\uc774\ud130 \uad6c\uc870\ub97c \ucd5c\ub300\ud55c \ub3d9\uc77c\ud558\uac8c \uc720\uc9c0\ud558\uae30 \uc704\ud574\uc11c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DB\uc758 \uceec\ub7fc\uc774 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4\uba74,<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE UserItem\n(\n    userID VARCHAR(64) NOT NULL,\n    itemCode INT NOT NULL,\n    itemCount INT NOT NULL,\n    createdAt DATETIME,\n    PRIMARY KEY(userID, itemCode)\n);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">SQL\uc744 \ud30c\uc2f1\ud574\uc11c \ub300\ub7b5 \ub2e4\uc74c\uacfc \uac19\uc740 TypeScript Model\uc744 \ub9cc\ub4e0\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export interface UserItem {\n    userID: string;\n    itemCode: number;\n    itemCount: number;\n    createdAt: Date;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ud074\ub77c\uc774\uc5b8\ud2b8 \uc5ed\uc2dc \uac19\uc740 SQL\uc744 \uae30\uc900\uc73c\ub85c C# Model\uc744 \uc0dd\uc131\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class UserItem\n{\n    public string userID;\n    public int itemCode;\n    public int itemCount;\n    public DateTime createdAt;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \uad6c\uc870\ub97c \uc0ac\uc6a9\ud558\uba74 DB \uc2a4\ud0a4\ub9c8\uac00 \ubcc0\uacbd\ub418\uc5c8\uc744 \ub54c \uc11c\ubc84\uc640 \ud074\ub77c\uc774\uc5b8\ud2b8 Model\uc744 \ub2e4\uc2dc \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ubb3c\ub860 \uc2e4\uc81c \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c\ub294 \uc11c\ubc84 \uc804\uc6a9 \uceec\ub7fc\uc774\ub098 \ubcf4\uc548\uc0c1 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \uc804\ub2ec\ud558\uba74 \uc548 \ub418\ub294 \ub370\uc774\ud130\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 DB Model\uacfc \ub124\ud2b8\uc6cc\ud06c DTO\ub97c \ud56d\uc0c1 \ub3d9\uc77c\ud558\uac8c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc544\ub2c8\ub2e4. \ud544\uc694\ud55c \uacbd\uc6b0 \ubcc4\ub3c4\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4 \ubd84\ub9ac\ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\uc11c\ubc84 DB Controller<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Node.js\uc5d0\uc11c\ub294 DB\uc5d0 \uc811\uadfc\ud558\ub294 \ucf54\ub4dc\uac00 \uc5ec\ub7ec \uacf3\uc5d0 \ud769\uc5b4\uc9c0\uc9c0 \uc54a\ub3c4\ub85d \uacf5\ud1b5 Controller\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uac8c\uc784 \ub370\uc774\ud130\ucc98\ub7fc \uc804\uccb4 \ub370\uc774\ud130\ub97c \uac00\uc838\uc624\ub294 \uacbd\uc6b0\uc5d0\ub294 \ube44\uad50\uc801 \ub2e8\uc21c\ud558\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Quary } from \".\/mysql-client\";\n\nexport class GameDataControllerBase&lt;T&gt; {\n    private _tbName: string;\n\n    constructor(tbName: string) {\n        this._tbName = tbName;\n    }\n\n    public GetAllData(): Promise&lt;Array&lt;T&gt;&gt; {\n        return new Promise&lt;Array&lt;T&gt;&gt;(async (resolve, reject) =&gt; {\n            let result: any =\n                await Quary(`SELECT * FROM ${this._tbName}`, undefined);\n\n            return resolve(result as Array&lt;T&gt;);\n        });\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc2e4\uc81c \uac8c\uc784 \ub370\uc774\ud130 Controller\ub294 \uc774 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export class ItemDataController\n    extends GameDataControllerBase&lt;ItemData&gt; {\n\n    constructor() {\n        super(\"ItemData\");\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\ub807\uac8c \ud574\ub450\uba74 \uac8c\uc784 \ub370\uc774\ud130\ub9c8\ub2e4 <code>SELECT * FROM ...<\/code> \uac19\uc740 \ucf54\ub4dc\ub97c \ubc18\ubcf5\ud574\uc11c \uc791\uc131\ud560 \ud544\uc694\uac00 \uc5c6\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uac8c\uc784 \ub370\uc774\ud130\ub294 \uc11c\ubc84\uc5d0\uc11c \uc790\uc8fc \ucc38\uc870\ub418\ub294 \ub370\uc774\ud130\uc774\uae30 \ub54c\ubb38\uc5d0 \ucc98\uc74c\ubd80\ud130 \uc804\uccb4 \ub370\uc774\ud130\ub97c \uac00\uc838\uc624\ub294 \ud615\ud0dc\ub97c \uae30\ubcf8\uc73c\ub85c \uc7a1\uc558\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">UserData Controller<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uc720\uc800 \ub370\uc774\ud130\ub294 \uc870\uae08 \ub2e4\ub974\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ub300\ubd80\ubd84\uc758 \uacbd\uc6b0 UUID \ud558\ub098\ub85c \ub370\uc774\ud130\ub97c \ucc3e\uac70\ub098, UUID\uc640 \ud2b9\uc815 Code\ub97c \uac19\uc774 \uc0ac\uc6a9\ud574\uc11c \ub370\uc774\ud130\ub97c \ucc3e\ub294\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>User UUID -&gt; UserData<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ub610\ub294<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>User UUID + Code -&gt; GameData<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c \uacf5\ud1b5 Controller\ub3c4 \ub450 \uac00\uc9c0 Key\ub97c \ubc1b\uc744 \uc218 \uc788\ub3c4\ub85d \ub9cc\ub4e4\uc5c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Quary } from \".\/mysql-client\";\n\nexport class UserGameDataControllerBase&lt;T&gt; {\n    protected _tbName: string = \"\";\n    protected _primaryKey: string = \"\";\n    protected _subPrimaryKey: string = \"\";\n\n    protected _columList: string&#91;];\n    protected _columnQuaryPart: string = \"\";\n    protected _questionMarkQuaryPart: string = \"\";\n\n    constructor(\n        tbName: string,\n        primaryKey: string,\n        subPrimaryKey: string,\n        template: T\n    ) {\n        this._tbName = tbName;\n        this._primaryKey = primaryKey;\n        this._subPrimaryKey = subPrimaryKey;\n\n        this._columList =\n            Object.getOwnPropertyNames(template);\n\n        this._columnQuaryPart =\n            this.GenerateColumQuaryPart();\n\n        this._questionMarkQuaryPart =\n            this.GenerateQuestionMarkQuaryPart();\n    }\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">INSERT\ub3c4 Model\uc744 \uae30\uc900\uc73c\ub85c \uc790\ub3d9\uc73c\ub85c \uc0dd\uc131\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public async InsertData(entity: T) {\n    await Quary(\n        `INSERT INTO ${this._tbName}\n         ${this._columnQuaryPart}\n         VALUES ${this._questionMarkQuaryPart};`,\n        this.GenerateEntityParams(entity)\n    );\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc11c \uc911\uc694\ud55c \uac83\uc740 SQL \ubb38\uc790\uc5f4\uc5d0 \uc2e4\uc81c \ub370\uc774\ud130\ub97c \uc9c1\uc811 \ub123\uc9c0 \uc54a\uace0 <code>?<\/code> \ud30c\ub77c\ubbf8\ud130\ub97c \uc0ac\uc6a9\ud55c\ub2e4\ub294 \uc810\uc774\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>private GenerateEntityParams(entity: T): Array&lt;any&gt; {\n    let params = new Array&lt;any&gt;();\n\n    for (let index = 0;\n         index &lt; this._columList.length;\n         index++) {\n\n        const element = this._columList&#91;index];\n\n        let descriptors =\n            Object.getOwnPropertyDescriptors(entity);\n\n        params.push(descriptors&#91;element].value);\n    }\n\n    return params;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ub530\ub77c\uc11c \uc2e4\uc81c SQL\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\ub85c \uc2e4\ud589\ub41c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSERT INTO UserItem\n(userID, itemCode, itemCount, createdAt)\nVALUES (?, ?, ?, ?);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc2e4\uc81c \uac12\uc740 \ubcc4\ub3c4\uc758 parameter \ubc30\uc5f4\ub85c \uc804\ub2ec\ud55c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">UserData \uc870\ud68c<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uc720\uc800\uc640 \ucf54\ub4dc \ub450 \uac1c\ub97c \uc0ac\uc6a9\ud558\ub294 \ub370\uc774\ud130\ub77c\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc870\ud68c\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public GetData(\n    primaryKey: string,\n    code: any\n): Promise&lt;T&gt; {\n\n    return new Promise&lt;T&gt;(async (resolve, reject) =&gt; {\n\n        let params = new Array&lt;any&gt;();\n\n        params.push(primaryKey);\n        params.push(code);\n\n        let result: any = await Quary(\n            `SELECT * FROM ${this._tbName}\n             WHERE ${this._primaryKey} = ?\n             AND ${this._subPrimaryKey} = ?;`,\n            params\n        );\n\n        return resolve(result&#91;0] as T);\n    });\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \uad6c\uc870\ub97c \uc0ac\uc6a9\ud558\uba74 \uc2e4\uc81c \uac8c\uc784 \ucf54\ub4dc\uc5d0\uc11c\ub294 SQL\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc9c0 \uc54a\ub294\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const item =\n    await userItemController.GetData(userID, itemCode);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ud544\uc694\ud55c \uacbd\uc6b0 \uc804\uccb4 \ub370\uc774\ud130\ub3c4 \uac00\uc838\uc62c \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public async GetAllData(\n    primaryKey: string\n): Promise&lt;Array&lt;T&gt;&gt; {\n\n    let params = new Array&lt;any&gt;();\n    params.push(primaryKey);\n\n    let result: any = await Quary(\n        `SELECT * FROM ${this._tbName}\n         WHERE ${this._primaryKey} = ?;`,\n        params\n    );\n\n    return result as Array&lt;T&gt;;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc0ad\uc81c\ub3c4 \ub3d9\uc77c\ud558\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public async DeleteData(\n    primaryKey: string,\n    code: any\n) {\n    let params = new Array&lt;any&gt;();\n\n    params.push(primaryKey);\n    params.push(code);\n\n    await Quary(\n        `DELETE FROM ${this._tbName}\n         WHERE ${this._primaryKey} = ?\n         AND ${this._subPrimaryKey} = ?;`,\n        params\n    );\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc720\uc800 \uc804\uccb4 \ub370\uc774\ud130\ub97c \uc0ad\uc81c\ud574\uc57c \ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 UUID\ub9cc \uc0ac\uc6a9\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public async DeleteAllData(primaryKey: string) {\n    let params = new Array&lt;any&gt;();\n    params.push(primaryKey);\n\n    await Quary(\n        `DELETE FROM ${this._tbName}\n         WHERE ${this._primaryKey} = ?;`,\n        params\n    );\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Update \uc5ed\uc2dc \ubcc0\uacbd\ud560 \uceec\ub7fc\uc744 \ubc1b\uc544\uc11c \ucc98\ub9ac\ud558\ub3c4\ub85d \ub9cc\ub4e4\uc5c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public async UpdateData(\n    primaryKey: string,\n    code: any,\n    entity: T,\n    ...updateColumn: string&#91;]\n) {\n    let params = new Array&lt;any&gt;();\n    let updateColumnQuaryPart = \"\";\n\n    for (let index = 0;\n         index &lt; updateColumn.length;\n         index++) {\n\n        const column = updateColumn&#91;index];\n\n        updateColumnQuaryPart += `${column} = ? `;\n\n        let descriptors =\n            Object.getOwnPropertyDescriptors(entity);\n\n        params.push(descriptors&#91;column].value);\n    }\n\n    params.push(primaryKey);\n    params.push(code);\n\n    await Quary(\n        `UPDATE ${this._tbName}\n         SET ${updateColumnQuaryPart}\n         WHERE ${this._primaryKey} = ?\n         AND ${this._subPrimaryKey} = ?;`,\n        params\n    );\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\ub7f0 \uc2dd\uc73c\ub85c \uacf5\ud1b5 CRUD\ub97c \ub9cc\ub4e4\uc5b4\ub450\uba74 \uc2e4\uc81c \ucf58\ud150\uce20 \uac1c\ubc1c\uc5d0\uc11c\ub294 DB \uc811\uadfc \uc790\uccb4\ubcf4\ub2e4 \ub370\uc774\ud130\uc758 \uc758\ubbf8\uc640 \uac8c\uc784 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Redis \uce90\uc2dc<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Redis\ub3c4 DB Controller\uc640 \ud06c\uac8c \ub2e4\ub974\uc9c0 \uc54a\uac8c \uad6c\uc131\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc720\uc800 \ub370\uc774\ud130\ub97c Key\ub97c \uae30\uc900\uc73c\ub85c \uc800\uc7a5\ud558\uace0 JSON\uc73c\ub85c \uc9c1\ub82c\ud654\ud588\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import IORedis from \"ioredis\";\n\nexport default class GameModelCacheBase&lt;T&gt; {\n\n    private _key: string = \"\";\n    private _redisClient: IORedis.Redis;\n\n    constructor(\n        key: string,\n        redisClient: IORedis.Redis\n    ) {\n        this._key = key;\n        this._redisClient = redisClient;\n    }\n\n    public async SetData(\n        userID: string,\n        model: T\n    ) {\n        await this._redisClient.set(\n            this._key + userID,\n            JSON.stringify(model)\n        );\n    }\n\n    public async GetData(\n        userID: string\n    ): Promise&lt;T&gt; {\n\n        return new Promise&lt;T&gt;(async (resolve, reject) =&gt; {\n\n            return resolve(\n                JSON.parse(\n                    await this._redisClient.get(\n                        this._key + userID\n                    ) as string\n                ) as T\n            );\n        });\n    }\n\n    public async ExistData(\n        userID: string\n    ): Promise&lt;boolean&gt; {\n\n        return new Promise&lt;boolean&gt;(\n            async (resolve, reject) =&gt; {\n\n                resolve(\n                    1 ==\n                    await this._redisClient.exists(\n                        this._key + userID\n                    )\n                );\n            }\n        );\n    }\n\n    public async RemoveData(\n        userID: string\n    ) {\n        await this._redisClient.del(\n            this._key + userID\n        );\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc2e4\uc81c Redis Key\ub294 \ud504\ub85c\uc81d\ud2b8 \uaddc\uce59\uc5d0 \ub530\ub77c \ub2e4\uc74c\uacfc \uac19\uc774 \ub9cc\ub4e4 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UserData:{UUID}\nInventory:{UUID}\nCharacter:{UUID}\nQuest:{UUID}:{QuestCode}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uad6d Redis\uc5d0\uc11c\ub3c4 \ub370\uc774\ud130 \uc131\uaca9\uc5d0 \ub530\ub77c \uc800\uc7a5\uc18c\ub97c \ub098\ub20c \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>GameData -&gt; Dictionary \/ \uacf5\ud1b5 \ub370\uc774\ud130<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>UserData -&gt; User UUID<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>UserGameData -&gt; User UUID + Code<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">DB\uc640 Redis\ub97c \ud558\ub098\ub85c \ubb36\uae30<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc11c \ud55c \ub2e8\uacc4 \ub354 \ub098\uac00\uba74 DB Controller\uc640 Redis Cache\ub97c \uac8c\uc784 \ucf54\ub4dc\uc5d0\uc11c \uc9c1\uc811 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \ud558\ub098\uc758 Repository\ub85c \ubb36\uc744 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uac00\uc7a5 \ub2e8\uc21c\ud55c \ud615\ud0dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export class UserDataRepository&lt;T&gt; {\n\n    private _db: UserGameDataControllerBase&lt;T&gt;;\n    private _cache: GameModelCacheBase&lt;T&gt;;\n\n    constructor(\n        db: UserGameDataControllerBase&lt;T&gt;,\n        cache: GameModelCacheBase&lt;T&gt;\n    ) {\n        this._db = db;\n        this._cache = cache;\n    }\n\n    public async GetData(\n        userID: string,\n        code: any\n    ): Promise&lt;T&gt; {\n\n        let cache =\n            await this._cache.GetData(userID);\n\n        if (cache != null) {\n            return cache;\n        }\n\n        let data =\n            await this._db.GetData(userID, code);\n\n        if (data != null) {\n            await this._cache.SetData(userID, data);\n        }\n\n        return data;\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uac1c\ub150\uc801\uc73c\ub85c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Get -&gt; Redis \ud655\uc778 -&gt; Hit -&gt; \ubc18\ud658<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Get -&gt; Redis \ud655\uc778 -&gt; Miss -&gt; DB \uc870\ud68c -&gt; Redis \uc800\uc7a5 -&gt; \ubc18\ud658<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7ec\uba74 \uac8c\uc784 \ub85c\uc9c1\uc5d0\uc11c\ub294 Redis\uc640 MySQL\uc744 \uc9c1\uc811 \uad6c\ubd84\ud560 \ud544\uc694\uac00 \uc5c6\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const userData =\n    await userDataRepository.GetData(userID, code);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Set \uc5ed\uc2dc Repository\uc5d0\uc11c DB\uc640 Redis\ub97c \uac19\uc774 \ucc98\ub9ac\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public async SetData(\n    userID: string,\n    code: any,\n    entity: T\n) {\n    await this._db.UpdateData(\n        userID,\n        code,\n        entity\n    );\n\n    await this._cache.SetData(\n        userID,\n        entity\n    );\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ub2e4\ub9cc \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0\uc11c\ub294 \uc5ec\uae30\uc11c \ub05d\ub098\uc9c0 \uc54a\ub294\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DB \uc800\uc7a5\uc740 \uc131\uacf5\ud588\ub294\ub370 Redis \uc800\uc7a5\uc774 \uc2e4\ud328\ud558\uac70\ub098 \ubc18\ub300 \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7a5\uc560 \uc0c1\ud669\uc5d0\uc11c \uc5b4\ub290 \ub370\uc774\ud130\ub97c \uae30\uc900\uc73c\ub85c \ubcf5\uad6c\ud560\uc9c0\uae4c\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4. \uce90\uc2dc \ubb34\ud6a8\ud654 \ubc29\uc2dd, TTL, Write Through, Cache Aside \uac19\uc740 \uc815\ucc45\ub3c4 \uc11c\ube44\uc2a4 \uc131\uaca9\uc5d0 \ub530\ub77c \uc120\ud0dd\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ub0b4\uac00 \uc0ac\uc6a9\ud55c \uad6c\uc870\uc5d0\uc11c\ub294 \uae30\ubcf8\uc801\uc73c\ub85c <strong>DB\ub97c \uc6d0\ubcf8 \ub370\uc774\ud130\ub85c \ubcf4\uace0 Redis\ub97c \ube60\ub978 \uc811\uadfc\uc744 \uc704\ud55c \uce90\uc2dc\ub85c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc<\/strong>\uc5d0 \uac00\uae5d\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\uc720\uc800 \uc811\uc18d \uc2dc \ub370\uc774\ud130 \ud750\ub984<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \uad6c\uc870\ub97c \uc2e4\uc81c \uc720\uc800 \uc138\uc158\uc5d0 \uc801\uc6a9\ud558\uba74 \ub300\ub7b5 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc774 \ub41c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Login\n -&gt; User UUID \ud655\uc778\n -&gt; DB UserData \uc870\ud68c\n -&gt; Redis \uce90\uc2f1\n -&gt; Session \uc2dc\uc791\n -&gt; \uac8c\uc784 \ub85c\uc9c1\uc5d0\uc11c Redis\/Repository \uc811\uadfc\n -&gt; \ub370\uc774\ud130 \ubcc0\uacbd\n -&gt; DB + Redis \ubc18\uc601\n -&gt; Session \uc885\ub8cc\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc811\uc18d \uc911\uc778 \uc720\uc800\uc758 \ub370\uc774\ud130\ub97c \uacc4\uc18d MySQL\uc5d0\uc11c \uc77d\ub294 \ub300\uc2e0 Redis\ub97c \uc911\uc2ec\uc73c\ub85c \uc811\uadfc\ud558\uac8c \ub9cc\ub4e4\uae30 \ub54c\ubb38\uc5d0 \ubc18\ubcf5\uc801\uc778 DB \uc811\uadfc\uc744 \uc904\uc77c \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud2b9\ud788 \uac8c\uc784\uc5d0\uc11c\ub294 \uc544\uc774\ud15c, \ud018\uc2a4\ud2b8, \uce90\ub9ad\ud130 \uc0c1\ud0dc\ucc98\ub7fc \uac19\uc740 \uc720\uc800 \ub370\uc774\ud130\ub97c \uc9e7\uc740 \uc2dc\uac04 \ub3d9\uc548 \ubc18\ubcf5\ud574\uc11c \uc870\ud68c\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7f0 \uce90\uc2f1 \uacc4\uce35\uc774 \uc758\ubbf8\uac00 \uc788\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Client Model<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uc11c\ubc84\uc5d0\uc11c \uc0ac\uc6a9\ud55c SQL\uc744 \uadf8\ub300\ub85c \ud074\ub77c\uc774\uc5b8\ud2b8 Model \uc0dd\uc131\uc5d0\ub3c4 \uc0ac\uc6a9\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">SQL\uc744 C# Model\ub85c \ud30c\uc2f1\ud574\uc11c GameData\uc640 UserData\ub97c \uad6c\uc131\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class ItemData\n{\n    public int code;\n    public string name;\n    public int price;\n}\n<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>public class UserItem\n{\n    public string userID;\n    public int itemCode;\n    public int itemCount;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">GameData\ub294 \ubaa8\ub4e0 \uc720\uc800\uac00 \uacf5\uc720\ud558\ub294 \ub370\uc774\ud130\uc774\uae30 \ub54c\ubb38\uc5d0 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uce90\uc2f1\ud574\ub458 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \uc544\uc774\ud15c \ub370\uc774\ud130\ub77c\uba74 \uc11c\ubc84\uc5d0\uc11c \ub9e4\ubc88 \ubc1b\uc544\uc624\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \ucd08\uae30 \ub2e4\uc6b4\ub85c\ub4dc \uc774\ud6c4 \ub85c\uceec\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uc2dd\uc774\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>GameData\n -&gt; Client Cache\n -&gt; \uac8c\uc784 \uc2e4\ud589 \uc911 \ubc18\ubcf5 \uc0ac\uc6a9\n -&gt; \ubc84\uc804 \ubcc0\uacbd\n -&gt; \ub370\uc774\ud130 \uc5c5\ub370\uc774\ud2b8\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ubc84\uc804 \uc815\ubcf4\ub97c \ubcc4\ub3c4\ub85c \uac00\uc9c0\uace0 \uc788\ub2e4\uba74 \uc11c\ubc84\uc640 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc84\uc804\uc744 \ube44\uad50\ud574\uc11c \ubcc0\uacbd\ub41c \uacbd\uc6b0\uc5d0\ub9cc \uc5c5\ub370\uc774\ud2b8\ud558\ub294 \ubc29\uc2dd\ub3c4 \uac00\ub2a5\ud558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">UserData\ub294 \uc720\uc800\ub9c8\ub2e4 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc77c\ubc18\uc801\uc73c\ub85c \ub85c\uadf8\uc778 \uacfc\uc815\uc5d0\uc11c \uac00\uc838\uc628\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Login\n -&gt; UserData Request\n -&gt; Server\n -&gt; UserData Response\n -&gt; Client Model \uc0dd\uc131\n -&gt; \uac8c\uc784\uc5d0\uc11c \uc0ac\uc6a9\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ub610\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 UserData\ub97c \uc800\uc7a5\ud574\ub450\uace0 \ud574\uc2dc\ub97c \ube44\uad50\ud574\uc11c \ubcc0\uacbd \uc5ec\ubd80\ub97c \ud655\uc778\ud558\ub294 \ubc29\ubc95\ub3c4 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Local UserData\n -&gt; Hash\n -&gt; Server Hash \ube44\uad50\n -&gt; \ub3d9\uc77c -&gt; Local Data \uc0ac\uc6a9\n -&gt; \ub2e4\ub984 -&gt; Server Data Download\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ub370\uc774\ud130 \ud06c\uae30\uc640 \ubcc0\uacbd \ube48\ub3c4\uc5d0 \ub530\ub77c \uc801\uc808\ud55c \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\uba74 \ub41c\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MVP \uad6c\uc870<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Model\uc774 \ub9cc\ub4e4\uc5b4\uc9c4 \uc774\ud6c4\uc5d0\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8 \uac1c\ubc1c\uc744 MVP \uad6c\uc870\ub85c \uc5f0\uacb0\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uae30\ubcf8\uc801\uc778 \uad6c\uc870\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Model &lt;-&gt; Presenter &lt;-&gt; View\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">View\ub294 UI \ud45c\ud604\uacfc \uc785\ub825\uc744 \ub2f4\ub2f9\ud558\uace0 Presenter\ub294 View\uc640 Model \uc0ac\uc774\uc758 \uc5f0\uacb0\uc744 \ub2f4\ub2f9\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ub098\ub294 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c Presenter\uc758 \uc0ac\uc6a9 \ubc94\uc704\uc5d0 \ub530\ub77c \uc774\ub984\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Presenter \ud558\ub098\uac00 \ud558\ub098\uc758 View\ub97c \ub2f4\ub2f9\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 <code>Ctrl<\/code>\uc774\ub77c\uace0 \uc774\ub984\uc744 \uc9c0\uc5c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Model &lt;-&gt; Ctrl &lt;-&gt; View\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \uc778\ubca4\ud1a0\ub9ac \ud558\ub098\ub97c \ub2f4\ub2f9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class InventoryCtrl\n{\n    private UserData _model;\n    private InventoryView _view;\n\n    public void Initialize(\n        UserData model,\n        InventoryView view)\n    {\n        _model = model;\n        _view = view;\n\n        Refresh();\n    }\n\n    private void Refresh()\n    {\n        _view.SetItemCount(\n            _model.itemCount\n        );\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ubc18\ub300\ub85c \ud558\ub098\uc758 Presenter\uac00 \uc5ec\ub7ec View\ub97c \uad00\ub9ac\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 <code>Manager<\/code>\ub77c\ub294 \uc774\ub984\uc744 \uc0ac\uc6a9\ud588\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Model &lt;-&gt; Manager &lt;-&gt; View1\n                    &lt;-&gt; View2\n                    &lt;-&gt; View3\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \uac8c\uc784 UI \uc804\uccb4\ub97c \uad00\ub9ac\ud574\uc57c \ud558\ub294 \uacbd\uc6b0\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class UIManager\n{\n    private InventoryView _inventoryView;\n    private QuestView _questView;\n    private CharacterView _characterView;\n\n    public void OpenInventory()\n    {\n        _inventoryView.Show();\n    }\n\n    public void OpenQuest()\n    {\n        _questView.Show();\n    }\n\n    public void OpenCharacter()\n    {\n        _characterView.Show();\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\uac83\uc740 MVP \ud328\ud134 \uc790\uccb4\ub97c \ubcc0\ud615\ud55c \uac83\uc774\ub77c\uae30\ubcf4\ub2e4\ub294 \ud504\ub85c\uc81d\ud2b8 \ub0b4\ubd80\uc5d0\uc11c \uc5ed\ud560\uc744 \uad6c\ubd84\ud558\uae30 \uc704\ud55c \ub124\uc774\ubc0d \uaddc\uce59\uc5d0 \uac00\uae5d\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Handler\uc640 System<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\ubaa8\ub4e0 \ub85c\uc9c1\uc744 Presenter\uc5d0 \ub123\uc9c0\ub294 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\ub7ec \uacf3\uc5d0\uc11c \uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 \ub370\uc774\ud130 \ucc98\ub9ac \ub85c\uc9c1\uc774\ub098 \uaddc\ubaa8\uac00 \ud070 \uac8c\uc784 \ub85c\uc9c1\uc740 <code>Handler<\/code> \ub610\ub294 <code>System<\/code>\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>View\n -&gt; Ctrl \/ Manager\n -&gt; Handler \/ System\n -&gt; Model\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \uc778\ubca4\ud1a0\ub9ac \uc544\uc774\ud15c \ucd94\uac00 \uac19\uc740 \ub85c\uc9c1\uc774 \uc5ec\ub7ec UI\uc5d0\uc11c \uc0ac\uc6a9\ub41c\ub2e4\uba74 Presenter\ub9c8\ub2e4 \uc9c1\uc811 \uad6c\ud604\ud558\uc9c0 \uc54a\uace0 Handler\ub85c \ubd84\ub9ac\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class InventoryHandler\n{\n    public bool AddItem(\n        UserData userData,\n        int itemCode,\n        int count)\n    {\n        \/\/ \uc544\uc774\ud15c \ucd94\uac00 \ub85c\uc9c1\n\n        return true;\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7ec\uba74 \uc5ec\ub7ec Presenter\uc5d0\uc11c \ub3d9\uc77c\ud55c Handler\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class InventoryCtrl\n{\n    private InventoryHandler _handler;\n\n    public void AddItem(\n        UserData userData,\n        int itemCode,\n        int count)\n    {\n        _handler.AddItem(\n            userData,\n            itemCode,\n            count\n        );\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uaddc\ubaa8\uac00 \ud070 \uc2dc\uc2a4\ud15c\uc774\ub77c\uba74 Handler\ubcf4\ub2e4 System \ub2e8\uc704\ub85c \ubd84\ub9ac\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \uc804\ud22c, \uc778\ubca4\ud1a0\ub9ac, \ud018\uc2a4\ud2b8, \uce90\ub9ad\ud130 \uc131\uc7a5 \uac19\uc740 \uae30\ub2a5\uc744 \ub3c5\ub9bd\uc801\uc778 System\uc73c\ub85c \uad6c\uc131\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">View Generator<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">View\ub3c4 \ud544\uc694\ud560 \ub54c \uc9c1\uc811 \uc0dd\uc131\ud558\ub294 \ucf54\ub4dc\uac00 \ubc18\ubcf5\ub418\uc9c0 \uc54a\ub3c4\ub85d <code>Generator<\/code>\ub97c \uc0ac\uc6a9\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inspector\uc5d0\uc11c \ubbf8\ub9ac \uc5f0\uacb0\ub418\uc5b4 \uc788\ub294 View\ub77c\uba74 \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0, \ub7f0\ud0c0\uc784\uc5d0 \uc0dd\uc131\ud574\uc57c \ud558\ub294 View\ub77c\uba74 Generator\uac00 \uc0dd\uc131\ud55c \ub4a4 Presenter\uc5d0 \uc8fc\uc785\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>public class InventoryGenerator\n{\n    public InventoryCtrl Generate(\n        UserData model)\n    {\n        InventoryView view =\n            CreateView();\n\n        InventoryCtrl ctrl =\n            new InventoryCtrl();\n\n        ctrl.Initialize(\n            model,\n            view\n        );\n\n        return ctrl;\n    }\n\n    private InventoryView CreateView()\n    {\n        \/\/ View \uc0dd\uc131\n        return new InventoryView();\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uacfc\uc801\uc73c\ub85c View \uc0dd\uc131 \ucc45\uc784\uacfc View \ub3d9\uc791 \ucc45\uc784\ub3c4 \ubd84\ub9ac\ub41c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Generator\n -&gt; View \uc0dd\uc131\n -&gt; Presenter \uc0dd\uc131\n -&gt; Model \uc8fc\uc785\n -&gt; View \uc8fc\uc785\n -&gt; \uc5f0\uacb0 \uc644\ub8cc\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\uc804\uccb4 \uad6c\uc870<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uad6d \uc774 \uad6c\uc870\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \uac01\uac01\uc758 Controller\ub098 Manager \ud074\ub798\uc2a4 \uc790\uccb4\uac00 \uc544\ub2c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ucc98\uc74c DB\ub97c \uc815\uc758\ud558\ub294 \ub2e8\uacc4\ubd80\ud130 \ud074\ub77c\uc774\uc5b8\ud2b8 UI\uae4c\uc9c0 \ub370\uc774\ud130\uac00 \ud558\ub098\uc758 \ud750\ub984\uc73c\ub85c \uc774\uc5b4\uc9c0\ub3c4\ub85d \ub9cc\ub4dc\ub294 \uac83\uc774 \ud575\uc2ec\uc774\uc5c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ERD\n -&gt; SQL\n -&gt; Server Model\n -&gt; DB Controller\n -&gt; Redis Cache\n -&gt; Repository\n -&gt; DTO\n -&gt; Client Model\n -&gt; MVP\n -&gt; Ctrl \/ Manager\n -&gt; Handler \/ System\n -&gt; View\n -&gt; Generator\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc11c\ubc84\uc5d0\uc11c\ub294 DB\ub97c \uc6d0\ubcf8 \ub370\uc774\ud130 \uc800\uc7a5\uc18c\ub85c \uc0ac\uc6a9\ud558\uace0 Redis\ub97c \uce90\uc2dc \uacc4\uce35\uc73c\ub85c \uc0ac\uc6a9\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DB \uc811\uadfc\uc740 Controller\ub85c \ucd94\uc0c1\ud654\ud558\uace0, Redis \uc5ed\uc2dc \ubcc4\ub3c4\uc758 Cache \ud074\ub798\uc2a4\ub85c \ucd94\uc0c1\ud654\ud55c\ub2e4. \uc774\ud6c4 Repository\uc5d0\uc11c \ub458\uc744 \ubb36\uc5b4 \uc2e4\uc81c \uac8c\uc784 \ub85c\uc9c1\uc5d0\uc11c\ub294 \uc800\uc7a5\uc18c\uc758 \uad6c\ud604\uc744 \uc9c1\uc811 \uc54c \ud544\uc694\uac00 \uc5c6\ub3c4\ub85d \ub9cc\ub4e0\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c\ub294 \uac19\uc740 SQL\uc744 \uae30\uc900\uc73c\ub85c Model\uc744 \uc0dd\uc131\ud558\uace0 GameData\uc640 UserData\ub97c \ubd84\ub9ac\ud55c\ub2e4. GameData\ub294 \uce90\uc2f1\ud558\uace0 \ubc84\uc804 \uae30\ubc18\uc73c\ub85c \uac31\uc2e0\ud558\uba70 UserData\ub294 \ub85c\uadf8\uc778 \uacfc\uc815\uc5d0\uc11c \uac00\uc838\uc624\uac70\ub098 \ub85c\uceec \ub370\uc774\ud130\uc640 \ud574\uc2dc\ub97c \ube44\uad50\ud574\uc11c \ud544\uc694\ud55c \uacbd\uc6b0 \uac31\uc2e0\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8 \uc704\uc5d0 MVP \uad6c\uc870\ub97c \uc801\uc6a9\ud558\uace0 Presenter \ud558\ub098\uac00 \ud558\ub098\uc758 View\ub97c \ub2f4\ub2f9\ud558\uba74 Ctrl, \uc5ec\ub7ec View\ub97c \uad00\ub9ac\ud558\uba74 Manager\ub77c\ub294 \uc774\ub984\uc73c\ub85c \uad6c\ubd84\ud588\ub2e4. \uacf5\ud1b5 \ub85c\uc9c1\uc740 Handler, \uaddc\ubaa8\uac00 \ud070 \uac8c\uc784 \ub85c\uc9c1\uc740 System\uc73c\ub85c \ubd84\ub9ac\ud558\uace0 \ub7f0\ud0c0\uc784 View \uc0dd\uc131\uc740 Generator\uac00 \ub2f4\ub2f9\ud558\ub3c4\ub85d \ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uad6d \ub0b4\uac00 \ub9cc\ub4e4\ub824\uace0 \ud588\ub358 \uac83\uc740 \ub2e8\uc21c\ud55c CRUD \ud074\ub798\uc2a4\uac00 \uc544\ub2c8\ub77c <strong>DB \uc2a4\ud0a4\ub9c8\ub97c \uae30\uc900\uc73c\ub85c \uc11c\ubc84\uc640 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ub370\uc774\ud130 \uad6c\uc870\ub97c \ub9de\ucd94\uace0, DB\uc640 Redis\ub97c \ucd94\uc0c1\ud654\ud55c \ub4a4, \uadf8 \ub370\uc774\ud130\ub97c MVP \uae30\ubc18\uc758 \ud074\ub77c\uc774\uc5b8\ud2b8 \uad6c\uc870\uae4c\uc9c0 \uc5f0\uacb0\ud558\ub294 \uacf5\ud1b5 \uac1c\ubc1c \uae30\ubc18<\/strong>\uc774\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud504\ub85c\uc81d\ud2b8\uac00 \ucee4\uc9c8\uc218\ub85d \ucf58\ud150\uce20 \ud558\ub098\ub97c \ucd94\uac00\ud560 \ub54c\ub9c8\ub2e4 DB \uc811\uadfc \ucf54\ub4dc, \uce90\uc2dc \ucf54\ub4dc, Model, UI \uc5f0\uacb0 \ucf54\ub4dc\ub97c \uac01\uac01 \uc0c8\ub85c \uc791\uc131\ud558\ub294 \uac83\uc740 \ube44\ud6a8\uc728\uc801\uc774\ub2e4. \ubc18\ub300\ub85c \uc774 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uacf5\ud1b5\ud654\ud574\ub450\uba74 \uc0c8\ub85c\uc6b4 \ub370\uc774\ud130 \ud14c\uc774\ube14\uc774 \ucd94\uac00\ub418\uc5b4\ub3c4 SQL\uc744 \uc791\uc131\ud558\uace0 Model\uc744 \uc0dd\uc131\ud55c \ub4a4 \ud544\uc694\ud55c Controller\uc640 View\ub97c \uc5f0\uacb0\ud558\ub294 \uc815\ub3c4\ub85c \uac1c\ubc1c\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \ubc29\uc2dd\uc758 \ud575\uc2ec\uc740 \uacb0\uad6d <strong>\ubc18\ubcf5\ub418\ub294 \ub370\uc774\ud130 \ucc98\ub9ac \uc791\uc5c5\uc744 \ucf54\ub4dc \uc0dd\uc131\uacfc \uacf5\ud1b5 \uacc4\uce35\uc73c\ub85c \ubc00\uc5b4\ub0b4\uace0, \uc2e4\uc81c \uac1c\ubc1c\uc790\ub294 \uac8c\uc784\uc758 \uaddc\uce59\uacfc \ucf58\ud150\uce20\uc5d0 \uc9d1\uc911\ud558\ub3c4\ub85d \ub9cc\ub4dc\ub294 \uac83<\/strong>\uc774\uc5c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uc11c\ubc84 \ub370\uc774\ud130 \ubaa8\ub378 \ubc0f \ud074\ub77c\uc774\uc5b8\ud2b8 \uad6c\uc870 \uc628\ub77c\uc778 \uac8c\uc784\uc774\ub098 \uc11c\ube44\uc2a4\ub97c \ub9cc\ub4e4 \ub54c \ub098\ub294 DB \uc124\uacc4\ubd80\ud130 \uc2dc\uc791\ud558\ub294 \ud3b8\uc774\ub2e4. \uac8c\uc784 \ub85c\uc9c1\ubd80\ud130 \ub9cc\ub4e4\uae30 \uc2dc\uc791\ud558\uba74 \ub098\uc911\uc5d0 \ub370\uc774\ud130 \uad6c\uc870\uac00 \uacc4\uc18d \ubc14\ub00c\uace0, \uadf8\ub54c\ub9c8\ub2e4 \uc11c\ubc84 Model\uc774\ub098 \ud074\ub77c\uc774\uc5b8\ud2b8 Model\uae4c\uc9c0 \uac19\uc774 \uc218\uc815\ud574\uc57c \ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\ub2e4. \uadf8\ub798\uc11c \ucc98\uc74c\uc5d0 ERD\ub97c \uc791\uc131\ud558\uace0 \ub370\uc774\ud130 \uad6c\uc870\ub97c \uc5b4\ub290 \uc815\ub3c4 \ud655\uc815\ud55c \ub2e4\uc74c \uad6c\ud604\uc744 \uc2dc\uc791\ud55c\ub2e4. \uae30\ubcf8\uc801\uc778 \uac1c\ubc1c \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. ERD \uc791\uc131 -&gt; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[31],"tags":[],"class_list":["post-2349","post","type-post","status-publish","format-standard","hentry","category-dev-notes"],"_links":{"self":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts\/2349","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2349"}],"version-history":[{"count":1,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts\/2349\/revisions"}],"predecessor-version":[{"id":2352,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts\/2349\/revisions\/2352"}],"wp:attachment":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2349"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2349"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2349"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}