{"id":16884,"date":"2026-06-19T14:53:38","date_gmt":"2026-06-19T05:53:38","guid":{"rendered":"http:\/\/www.gisdeveloper.co.kr\/?p=16884"},"modified":"2026-06-19T15:07:00","modified_gmt":"2026-06-19T06:07:00","slug":"solid","status":"publish","type":"post","link":"http:\/\/www.gisdeveloper.co.kr\/?p=16884","title":{"rendered":"SOLID"},"content":{"rendered":"<p>SOLID\ub294 \uac1d\uccb4 \uc9c0\ud5a5 \ud504\ub85c\uadf8\ub798\ubc0d \ubc0f \uc124\uacc4(OOP)\uc5d0\uc11c \uc88b\uc740 \uc18c\ud504\ud2b8\uc6e8\uc5b4\ub97c \ub9cc\ub4e4\uae30 \uc704\ud574 \uc9c0\ucf1c\uc57c \ud558\ub294 5\uac00\uc9c0 \ud575\uc2ec \uc124\uacc4 \uc6d0\uce59\uc758 \uc55e \uae00\uc790\ub97c \ub534 \uc57d\uc5b4\uc785\ub2c8\ub2e4. \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4(Uncle Bob)\uc774 2000\ub144\ub300 \ucd08\ubc18\uc5d0 \uc815\ub9bd\ud55c \uc774 \uc6d0\uce59\ub4e4\uc758 \ud575\uc2ec \ubaa9\uc801\uc740, \uc2dc\uac04\uc774 \uc9c0\ub098\ub3c4 \uc720\uc9c0\ubcf4\uc218\uac00 \uc27d\uace0, \ud655\uc7a5\uc131\uc774 \ub192\uc73c\uba70, \ubcc0\ud654\uc5d0 \uc720\uc5f0\ud558\uac8c \ub300\ucc98\ud560 \uc218 \uc788\ub294 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uac83\uc785\ub2c8\ub2e4. SOLID\ub97c \uad6c\uc131\ud558\ub294 \uc6d0\uce59\uc740 SRP, OCP, LIP, ISP, DIP\uc785\ub2c8\ub2e4.<\/p>\n<h3>SRP<\/h3>\n<p>Single Responsibility Principle\ub85c \ub2e8\uc77c \ucc45\uc784 \uc6d0\uce59\uc785\ub2c8\ub2e4. \ud558\ub098\uc758 \ud074\ub798\uc2a4\ub294 \ub2e8 \ud558\ub098\uc758 \ucc45\uc784(\ubcc0\uacbd \uc774\uc720)\ub9cc\uc744 \uac00\uc838\uc57c \ud55c\ub2e4\ub294 \uac83\uc778\ub370, \uc2e4\ubb34\uc5d0\uc11c\ub294 \uc624\uc9c1 \ud558\ub098\uc758 \uc561\ud130(Actor, \uae30\ub2a5 \ubcc0\uacbd\uc744 \uc694\uccad\ud558\ub294 \uc9d1\ub2e8)\uc5d0 \ub300\ud574\uc11c\ub9cc \ucc45\uc784\uc744 \uc838\uc57c \ud55c\ub2e4\ub85c \uc801\uc6a9\ud558\ub294\uac8c \uc790\uc5f0\uc2a4\ub7fd\uc2b5\ub2c8\ub2e4.<\/p>\n<p>SRP\uac00 \uc801\uc6a9\ub41c \uc608\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"typescript\">\r\n\/\/ 1. \ub85c\uae45 \uc804\ub2f4 \ud074\ub798\uc2a4 (\ubcc0\uacbd \uc774\uc720: \ub85c\uadf8 \ud3ec\ub9f7 \ubcc0\uacbd, \uc800\uc7a5\uc18c \ubcc0\uacbd \ub4f1)\r\nclass Logger {\r\n    public log(message: string): void {\r\n        const timestamp = new Date().toISOString();\r\n        console.log(`[LOG] [${timestamp}] - ${message}`);\r\n    }\r\n}\r\n\r\n\/\/ 2. \uc778\uc99d \uc804\ub2f4 \ud074\ub798\uc2a4 (\ubcc0\uacbd \uc774\uc720: JWT \ub3c4\uc785, OAuth2 \ub3c4\uc785 \ub4f1)\r\nclass AuthService {\r\n    public authenticate(token: string): boolean {\r\n        console.log(`\ud1a0\ud070 \uc720\ud6a8\uc131\uc744 \uac80\uc99d\ud569\ub2c8\ub2e4: ${token}`);\r\n        return true;\r\n    }\r\n}\r\n\r\n\/\/ 3. \uc0ac\uc6a9\uc790 \uc815\ubcf4 \uad00\ub9ac \uc804\ub2f4 \ud074\ub798\uc2a4 (\ubcc0\uacbd \uc774\uc720: \ud504\ub85c\ud544 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1 \ubcc0\uacbd)\r\n\/\/ \uc758\uc874\uc131 \uc8fc\uc785(DI)\uc744 \ud1b5\ud574 \uc678\ubd80\uc5d0\uc11c \ub85c\uac70\ub97c \uc8fc\uc785\ubc1b\uc544 \uc0ac\uc6a9\ud569\ub2c8\ub2e4.\r\nclass UserService {\r\n    private logger: Logger;\r\n\r\n    constructor(logger: Logger) {\r\n        this.logger = logger;\r\n    }\r\n\r\n    public updateProfile(userId: string, data: any): void {\r\n        console.log(`\uc0ac\uc6a9\uc790 ${userId}\uc758 \ud504\ub85c\ud544\uc744 \uc5c5\ub370\uc774\ud2b8\ud569\ub2c8\ub2e4.`);\r\n        \r\n        \/\/ \uc790\uc2e0\uc758 \ucc45\uc784\uc774 \uc544\ub2cc \ub85c\uadf8 \ucd9c\ub825\uc740 \uc8fc\uc785\ubc1b\uc740 Logger \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud569\ub2c8\ub2e4.\r\n        this.logger.log(`\ud504\ub85c\ud544 \uc5c5\ub370\uc774\ud2b8 \uc644\ub8cc (UserId: ${userId})`);\r\n    }\r\n}\r\n\r\nfunction run() {\r\n    const logger = new Logger();\r\n    const authService = new AuthService();\r\n    const userService = new UserService(logger);\r\n\r\n    \/\/ \uac01\uc790 \ub9e1\uc740 \ucc45\uc784\ub9cc \uc218\ud589\r\n    if (authService.authenticate(\"valid-token\")) {\r\n        userService.updateProfile(\"user_123\", { name: \"Gemini\" });\r\n    }\r\n}\r\n\r\nrun();\r\n<\/pre>\n<p>SRP\uac00 \uc801\uc6a9\ub420 \uacbd\uc6b0 \uc787\uc810\uc744 \uc0dd\uac01\ud574 \ubcf4\uba74&#8230; <\ud074\ub798\uc2a4\uac00 \uc791\uace0 \ub2e8\uc21c\ud574\uc838 \uc720\ub2db \ud14c\uc2a4\ud2b8 \uc791\uc131\uc774 \ub9e4\uc6b0 \uc218\uc6d4\ud574 \uc9c0\uace0 \uac01 \ud074\ub798\uc2a4\ub294 \ubcf8\uc5f0\uc758 \uc784\ubb34\uc5d0\ub9cc \uc9d1\uc9d1\ud558\ubbc0\ub85c \ucf54\ub4dc\uac00 \ub2e8\ub2e8\ud574 \uc9d1\ub2c8\ub2e4. \ub2e8\ub2e8\ud558\ub2e4\ub294 \uc758\ubbf8\ub294 \uc624\ub958 \ubc1c\uc0dd\uc774 \uc801\ub2e4\ub294 \uac83\uc785\ub2c8\ub2e4.<\/p>\n<h3>OCP<\/h3>\n<p>Open-Closed Principle\uc73c\ub85c \uac1c\ubc29-\ud3d0\uc1e0 \uc6d0\uce59\uc785\ub2c8\ub2e4. \ud655\uc7a5\uc5d0\ub294 \uac1c\ubc29\ub418\uc5b4 \uc788\uace0 \ubcc0\uacbd\uc5d0\ub294 \ud3d0\uc1e0\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4\ub294 \uc6d0\uce59\uc778\ub370\uc694. \ubcc0\uacbd\uc5d0\ub294 \ud3d0\uc1e0\ub418\uc5b4 \uc788\ub2e4(Closed for modi)\ub77c\ub294 \uac83\uc740 \uc2e0\uaddc \uae30\ub2a5 \ucd94\uac00 \uc2dc \ub2e4\ub978 \uae30\ub2a5\uc5d0 \ub300\ud55c \ucf54\ub4dc \uc218\uc815\uc740 \uae08\uc9c0\ud55c\ub2e4\uc774\uace0 \ud655\uc7a5\uc5d0\ub294 \uac1c\ubc29\ub418\uc5b4 \uc788\ub2e4(Open for extension)\ub294 \uc2e0\uaddc \uae30\ub2a5 \ucd94\uac00 \uc2dc \uc81c\uc57d \uc5c6\uc774 \ucf54\ub4dc \uc791\uc131 \uac00\ub2a5\ud574\uc57c \ud55c\ub2e4\ub294 \uac83\uc785\ub2c8\ub2e4. SRP \uc801\uc6a9\uc744 \uc704\ud55c \uad6c\uccb4\uc801\uc778 \ub3c4\uad6c\ub294 \uc778\ud130\ud398\uc774\uc2a4\uc640 \ucd94\uc0c1 \ud074\ub798\uc2a4\uc785\ub2c8\ub2e4.<\/p>\n<p>OCP\uac00 \uc801\uc6a9\ub41c \uc608\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"typescript\">\r\n\/\/ \uacf5\ud1b5 \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758 (\uc774 \ud2c0\uc740 \ubcc0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4)\r\ninterface PaymentMethod {\r\n    pay(): void;\r\n}\r\n\r\n\/\/ \uac01 \uacb0\uc81c \uc218\ub2e8\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\uccb4\uc801\uc778 \ub85c\uc9c1\uc744 \uad6c\ud604\ud569\ub2c8\ub2e4.\r\nclass KakaoPay implements PaymentMethod {\r\n    public pay(): void {\r\n        console.log(\"\uce74\uce74\uc624\ud398\uc774\ub85c \uc548\uc804\ud558\uac8c \uacb0\uc81c\ud569\ub2c8\ub2e4.\");\r\n    }\r\n}\r\n\r\nclass NaverPay implements PaymentMethod {\r\n    public pay(): void {\r\n        console.log(\"\ub124\uc774\ubc84\ud398\uc774\ub85c \uc548\uc804\ud558\uac8c \uacb0\uc81c\ud569\ub2c8\ub2e4.\");\r\n    }\r\n}\r\n\r\n\/\/ \ud83d\udca1 \uc0c8\ub85c\uc6b4 \uacb0\uc81c \uc218\ub2e8\uc774 \ucd94\uac00\ub418\uc5b4\ub3c4 \uae30\uc874 \ucf54\ub4dc\ub97c \uac74\ub4dc\ub9b4 \ud544\uc694 \uc5c6\uc774 \ud30c\uc77c\ub9cc \uc0c8\ub85c \ub9cc\ub4e4\uba74 \ub429\ub2c8\ub2e4 (\ud655\uc7a5\uc5d0 \uc5f4\ub9bc)\r\nclass TossPay implements PaymentMethod {\r\n    public pay(): void {\r\n        console.log(\"\ud1a0\uc2a4\ud398\uc774\ub85c \uc548\uc804\ud558\uac8c \uacb0\uc81c\ud569\ub2c8\ub2e4.\");\r\n    }\r\n}\r\n\r\n\/\/ \uacb0\uc81c \ub9e4\ub2c8\uc800\ub294 \uad6c\uccb4\uc801\uc778 \ud074\ub798\uc2a4\uac00 \uc544\ub2cc \uc778\ud130\ud398\uc774\uc2a4(PaymentMethod)\uc5d0\ub9cc \uc758\uc874\ud569\ub2c8\ub2e4.\r\nclass PaymentManager {\r\n    \/\/ \uc0c8\ub85c\uc6b4 \uacb0\uc81c \ubc29\uc2dd\uc774 \uc544\ubb34\ub9ac \ub298\uc5b4\ub098\ub3c4 \uc774 \uba54\uc11c\ub4dc\ub294 \ub2e8 \ud55c \uc904\ub3c4 \uc218\uc815\ud560 \ud544\uc694\uac00 \uc5c6\uc2b5\ub2c8\ub2e4 (\ubcc0\uacbd\uc5d0 \ub2eb\ud798).\r\n    public processPayment(paymentMethod: PaymentMethod): void {\r\n        paymentMethod.pay();\r\n    }\r\n}\r\n\r\nfunction runPaymentSystem() {\r\n    const manager = new PaymentManager();\r\n\r\n    const kakao = new KakaoPay();\r\n    const toss = new TossPay(); \/\/ \uc0c8\ub86d\uac8c \ucd94\uac00\ub41c \uacb0\uc81c \uc218\ub2e8\r\n\r\n    manager.processPayment(kakao);\r\n    manager.processPayment(toss); \/\/ \uae30\uc874 \uacb0\uc81c \ub9e4\ub2c8\uc800 \ucf54\ub4dc \uc218\uc815 \uc5c6\uc774 \uadf8\ub300\ub85c \ud655\uc7a5 \uc801\uc6a9 \uac00\ub2a5\r\n}\r\n\r\nrunPaymentSystem();\r\n<\/pre>\n<p>SRP\uc758 \uc7a5\uc810\uc744 \uc0dd\uac01\ud574 \ubcf4\uba74&#8230; \uc0c8\ub85c\uc6b4 \uae30\ub2a5\uc744 \ucd94\uac00\ud560\ub54c \uae30\uc874 \ucf54\ub4dc \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \uc2dc\ud0a4\uba70 \uae30\ub2a5\uc744 \ucef4\ud3ec\ub10c\ud2b8 \ub2e8\uc704\ub85c \uac1c\ubc1c\ud558\uc5ec \ud50c\ub7ec\uadf8\uc778\ucc98\ub7fc \uc27d\uac8c \ucd94\uac00\ud558\uc5ec \uc870\ub9bd\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc785\ub2c8\ub2e4.<\/p>\n<h3>LSP<\/h3>\n<p>Liskov Substitution Principle\uc73c\ub85c \ub9ac\uc2a4\ucf54\ud504 \uce58\ud658 \uc6d0\uce59\uc785\ub2c8\ub2e4. OOP\uc758 \uc62c\ubc14\ub978 \ub2e4\ud615\uc131 \uad6c\ud604\uc744 \uc704\ud55c \uc0c1\uc18d \uaddc\uce59\uc744 \uc815\uc758\ud55c \uac83\uc73c\ub85c \uc11c\ube0c \ud0c0\uc785\uc740 \ud56d\uc0c1 \uc288\ud37c \ud0c0\uc785\uc744 \ub300\uccb4\ud560 \uc218 \uc788\uc5b4\uc57c \ud55c\ub2e4\uc640 \uc790\uc2dd \ud074\ub798\uc2a4\ub294 \ubd80\ubaa8 \ud074\ub798\uc2a4\uc758 \ucd94\uc0c1 \ub9e4\uc11c\ub4dc\ub9cc\uc744 public\uc73c\ub85c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uac15\uc870\ud55c \uc6d0\uce59\uc785\ub2c8\ub2e4.<\/p>\n<p>LSP\uac00 \uc801\uc6a9\ub41c \uc608\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"typescript\">\r\n\/\/ \ub450 \ub3c4\ud615\uc758 \uacf5\ud1b5\uc810\uc740 '\uba74\uc801\uc744 \uad6c\ud560 \uc218 \uc788\ub2e4'\ub294 \uac83\ubfd0\uc785\ub2c8\ub2e4.\r\ninterface Shape {\r\n    getArea(): number;\r\n}\r\n\r\n\/\/ \uc9c1\uc0ac\uac01\ud615\uc740 \uc790\uc2e0\uc758 \uc131\uc9c8\uc5d0 \ub9de\uac8c \uad6c\ud604\ud569\ub2c8\ub2e4.\r\nclass Rectangle implements Shape {\r\n    constructor(private width: number, private height: number) {}\r\n\r\n    public setWidth(width: number): void {\r\n        this.width = width;\r\n    }\r\n\r\n    public setHeight(height: number): void {\r\n        this.height = height;\r\n    }\r\n\r\n    public getArea(): number {\r\n        return this.width * this.height;\r\n    }\r\n}\r\n\r\n\/\/ \uc815\uc0ac\uac01\ud615\ub3c4 \uc790\uc2e0\uc758 \uc131\uc9c8\uc5d0 \ub9de\uac8c \uad6c\ud604\ud569\ub2c8\ub2e4. \uc9c1\uc0ac\uac01\ud615\uc744 \uc0c1\uc18d\ubc1b\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.\r\nclass Square implements Shape {\r\n    constructor(private side: number) {}\r\n\r\n    public setSide(side: number): void {\r\n        this.side = side;\r\n    }\r\n\r\n    public getArea(): number {\r\n        return this.side * this.side;\r\n    }\r\n}\r\n\r\n\/\/ \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uad6c\uccb4\uc801\uc778 \uac00\ub85c\/\uc138\ub85c \uc218\uc815\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \r\n\/\/ \uc624\uc9c1 '\ucd94\uc0c1\ud654\ub41c Shape \uc778\ud130\ud398\uc774\uc2a4\uc758 getArea \uaddc\uc57d'\uc5d0\ub9cc \uc758\uc874\ud569\ub2c8\ub2e4.\r\nfunction printArea(shape: Shape) {\r\n    console.log(`\uba74\uc801: ${shape.getArea()}`);\r\n}\r\n\r\nconst myRect = new Rectangle(5, 4);\r\nconst mySquare = new Square(5);\r\n\r\nprintArea(myRect);   \/\/ \uba74\uc801: 20 (\uc758\ub3c4\ub300\ub85c \ub3d9\uc791)\r\nprintArea(mySquare); \/\/ \uba74\uc801: 25 (\uc758\ub3c4\ub300\ub85c \ub3d9\uc791)\r\n<\/pre>\n<p>LSP\uc744 \uace0\ub824\ud560 \ub54c \uccb4\ud06c\ud574\uc57c\ud560 \uac83\uc744 \uace0\ubbfc\ud574 \ubcf4\uba74&#8230; \uba3c\uc800 \uc11c\ube0c \ud074\ub798\uc2a4\uac00 \uc288\ud37c \ud074\ub798\uc2a4\uc758 \ub9e4\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud560 \ub54c \uc758\ubbf8\ub97c \uc65c\uace1\ud558\uc9c0 \uc54a\ub294\uac00? \uadf8\ub9ac\uace0 \uc11c\ube0c \ud074\ub798\uc2a4\uac00 \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc608\uc678 \uaddc\uc57d(\uc804\uc81c \uc870\uac74)\uc744 \uae68\uc9c0 \uc54a\ub294\uac00? \uc785\ub2c8\ub2e4. \uc544\uc6b8\ub7ec \uc0c1\uc18d\uc740 \ud589\ub3d9\uc758 \uc77c\uce58\uc131\uc774 \ubcf4\uc7a5\ub420\ub54c \uc0ac\uc6a9\ub418\ub294 \uac83\uc774\uc9c0 \uc5b8\uc5b4\uc801 \uc9c1\uad00\uc774 \uc544\ub2d9\ub2c8\ub2e4. \uc989, \uc815\uc0ac\uac01\ud615\uc740 \uc9c1\uc0ac\uac01\ud615\uc744 \uc0c1\uc18d\ubc1b\uc744 \uc218 \uc788\ub294\uac00\ub77c\ub294 \uc9c8\ubb38\uc5d0\uc11c \uc18d\uc131\uc740 \uc0c1\uc18d\ubc1b\ub294 \ub300\uc0c1\uc774 \uc544\ub2c8\ubbc0\ub85c \uc815\uc0ac\uac01\ud615\uc740 \uc9c1\uc0ac\uac01\ud615\uc744 \uc0c1\uc18d\ubc1b\uae30\uc5d0\ub294 \uc801\ud569\ud558\uc9c0 \uc54a\ub2e4\uc785\ub2c8\ub2e4.<\/p>\n<h3>ISP<\/h3>\n<p>Interface Segregation Principle\ub85c \uc778\ud130\ud398\uc774\uc2a4 \ubd84\ub9ac \uc6d0\uce59\uc785\ub2c8\ub2e4. \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc790\uc2e0\uc774 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \ub9e4\uc11c\ub4dc\uc5d0 \uc758\uc874\ud558\ub3c4\ub85d \uac15\uc81c\ub418\uc5b4\uc11c\ub294 \uc548\ub41c\ub2e4\ub294 \uc6d0\uce59\uc73c\ub85c \ud558\ub098\uc758 \ub9cc\ub2a5 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc9c0 \ub9d0\uace0 \ubaa9\uc801\uc5d0 \ub530\ub77c \uc5ec\ub7ec \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ucabc\uac1c\ub77c\ub294 \uac83\uc785\ub2c8\ub2e4.<\/p>\n<p>ISP\uac00 \uc801\uc6a9\ub41c \uc608\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"typescript\">\r\n\/\/ \uc5ed\ud560\uc744 \uc587\uac8c \ucabc\uac20 \uc5ed\ud560 \uc778\ud130\ud398\uc774\uc2a4\ub4e4\r\ninterface Printer {\r\n    print(): void;\r\n}\r\n\r\ninterface Scanner {\r\n    scan(): void;\r\n}\r\n\r\ninterface FaxMachine {\r\n    fax(): void;\r\n}\r\n\r\n\/\/ \ubcf4\uae09\ud615 \ud504\ub9b0\ud130\ub294 \uc624\uc9c1 'Printer' \uc778\ud130\ud398\uc774\uc2a4\ub9cc \uad6c\ud604\ud569\ub2c8\ub2e4. (\uae54\ub054)\r\nclass EconomicPrinter implements Printer {\r\n    public print(): void {\r\n        console.log(\"\ud751\ubc31\uc73c\ub85c \ubb38\uc11c\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4.\");\r\n    }\r\n}\r\n\r\n\/\/ \uace0\uae09\ud615 \ubcf5\ud569\uae30\ub294 \ud544\uc694\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub4e4\uc744 \ub2e4\uc911 \uc0c1\uc18d(\uad6c\ud604)\ud558\uc5ec \uc870\ud569\ud569\ub2c8\ub2e4.\r\nclass AllInOnePrinter implements Printer, Scanner, FaxMachine {\r\n    public print(): void { console.log(\"\uceec\ub7ec\ub85c \ubb38\uc11c\ub97c \ucd9c\ub825\ud569\ub2c8\ub2e4.\"); }\r\n    public scan(): void { console.log(\"\uace0\ud654\uc9c8\ub85c \uc2a4\uce94\ud569\ub2c8\ub2e4.\"); }\r\n    public fax(): void { console.log(\"\ud329\uc2a4\ub97c \ubcf4\ub0c5\ub2c8\ub2e4.\"); }\r\n}\r\n\r\n\/\/ \ud074\ub77c\uc774\uc5b8\ud2b8 \ud568\uc218\ub3c4 \uac70\ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc804\uccb4\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \r\n\/\/ \uc790\uae30\uac00 \ub531 \ud544\uc694\ud55c \uc587\uc740 \uc778\ud130\ud398\uc774\uc2a4\uc5d0\ub9cc \uc758\uc874\ud558\uac8c \ub429\ub2c8\ub2e4.\r\nclass OfficeWorker {\r\n    \/\/ \uc774 \uc9c1\uc6d0\uc740 \uc624\uc9c1 \uc2a4\uce94 \uae30\ub2a5\ub9cc \ud544\uc694\ub85c \ud569\ub2c8\ub2e4.\r\n    public doScanJob(scanner: Scanner) {\r\n        scanner.scan();\r\n    }\r\n}\r\n\r\nconst worker = new OfficeWorker();\r\nconst premiumMachine = new AllInOnePrinter();\r\nconst ecoMachine = new EconomicPrinter();\r\n\r\nworker.doScanJob(premiumMachine); \/\/ \uc815\uc0c1 \uc791\ub3d9\r\n\r\n\/\/ \ud83d\udca1 \uc560\ucd08\uc5d0 \uc2a4\uce94 \uae30\ub2a5\uc774 \uc5c6\ub294 ecoMachine\uc740 \ud0c0\uc785 \uac80\uc0ac \ub2e8\uacc4\uc5d0\uc11c \uac78\ub7ec\uc9c0\ubbc0\ub85c \r\n\/\/ \ucef4\ud30c\uc77c \uc5d0\ub7ec\ub97c \ud1b5\ud574 \uc7a0\uc7ac\uc801 \ubc84\uadf8\ub97c \uc0ac\uc804\uc5d0 \ubc29\uc9c0\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.\r\n\/\/ worker.doScanJob(ecoMachine); \/\/ \ucef4\ud30c\uc77c \uc5d0\ub7ec \ubc1c\uc0dd!\r\n<\/pre>\n<p>ISP\uc774 \uc801\uc6a9\ub420 \uacbd\uc6b0 \uc7a5\uc810\uc744 \uc0dd\uac01\ud574 \ubcf4\uba74&#8230; \uc778\ud130\ud398\uc774\uc2a4 \ubcc4\ub85c \uc798 \ub098\ub220\uc838 \uc788\ub2e4\uba74 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \ubcc0\uacbd\uc5d0 \ub530\ub978 \uad6c\ud604 \ud074\ub798\uc2a4 \ubcc0\uacbd\uc774 \ucd5c\uc18c\ud654\ub41c\ub2e4\ub294 \uac83\uc785\ub2c8\ub2e4. \ucc38\uace0\ub85c SRP\ub294 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \ub2e8\uc77c \ucc45\uc784\uc744 \uac15\uc870\ud55c\ub2e4\uba74 ISP\ub294 \uc778\ud130\ud398\uc774\uc2a4\uc758 \ub2e8\uc77c \ucc45\uc784\uc744 \uac15\uc870\ud558\ub294 \uc6d0\uce59\uc785\ub2c8\ub2e4.<\/p>\n<p><P>\uc774 \uc6d0\uce59\uc5d0 \ub300\ud55c \uccb4\ud06c \uc0ac\ud56d\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\uc5d0\uc11c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ub9e4\uc11c\ub4dc \uc911 \ube48\uce78 \ub610\ub294 \uc608\uc678\ub85c \ucc98\ub9ac\ud558\ub294 \uacbd\uc6b0\uac00 \uc788\ub2e4\uba74 ISP \uc704\ubc18\uc77c \uac00\ub2a5\uc131\uc774 \ub192\uc2b5\ub2c8\ub2e4.<\/P><\/p>\n<h3>DIP<\/h3>\n<p>Dependency Inversion Princlple\ub85c \uc758\uc874 \uc5ed\uc804 \uc6d0\uce59\uc785\ub2c8\ub2e4. \uace0\uc218\uc900 \ubaa8\ub4c8\uc740 \uc800\uc218\uc900 \ubaa8\ub4c8\uc73c \uad6c\ud604\uc5d0 \uc758\uc874\ud574\uc11c\ub294 \uc548\ub41c\ub2e4\ub294 \uac83\uc73c\ub85c \uace0\uc218\uc900\uc774\ub098 \uc800\uc218\uc900 \ubaa8\ub450 \ubcc4\ub3c4\uc758 \ucd94\uc0c1\ud654\ub41c \ubaa8\ub4c8\uc5d0 \uc758\uc874\ud574\uc57c \ud55c\ub2e4\ub294 \uac83\uc785\ub2c8\ub2e4. \uc804\ud1b5\uc801\uc778 \ubaa8\ub4c8 \ubc29\uc2dd\uc758 \uac1c\ubc1c\uc740 \uace0\uc218\uc900 \ubaa8\ub4c8\uc774 \uc800\uc218\uc900 \ubaa8\ub4c8\uc5d0 \uc758\uc874\ud588\uc9c0\ub9cc DIP\uc744 \uc900\uc218\ud558\uba74 \uc800\uc218\uc900\uacfc \uace0\uc218\uc900 \ubaa8\ub4c8 \uac04\uc758 \uc758\uc874\uc740 \uc81c\uac70\ub418\uace0 \ub450 \ubaa8\ub4c8\uc774 \ubcc4\ub3c4\uc758 \ucd94\uc0c1\ud654 \ubaa8\ub4c8\uc5d0 \uc758\uc874\ud558\uac8c \ub429\ub2c8\ub2e4. \uc989 \uc758\uc874 \ubc29\ud5a5 \uc5ed\uc804\ub429\ub2c8\ub2e4. <\/p>\n<p>DIP\uac00 \uc801\uc6a9\ub41c \uc608\ub294 \ub2e4\uc74c\uacfc \uac19\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"typescript\">\r\n\/\/ \uace0\uc218\uc900 \ubaa8\ub4c8\uacfc \uc800\uc218\uc900 \ubaa8\ub4c8\uc774 \ubaa8\ub450 \uc758\uc874\ud560 \uc911\uc2ec \ud2c0\uc785\ub2c8\ub2e4.\r\ninterface MessageSender {\r\n    sendMessage(message: string): void;\r\n}\r\n\r\n\/\/ [\uc800\uc218\uc900 \ubaa8\ub4c8] \uc0c8\ub85c\uc6b4 \uc54c\ub9bc \uc218\ub2e8\uc774 \ucd94\uac00\ub418\uc5b4\ub3c4 \uc778\ud130\ud398\uc774\uc2a4\ub9cc \ub9de\ucdb0\uc11c \ub9cc\ub4e4\uba74 \ub429\ub2c8\ub2e4.\r\nclass NaverSmsService implements MessageSender {\r\n    public sendMessage(message: string): void {\r\n        console.log(`[\ub124\uc774\ubc84 API] SMS \uc804\uc1a1: ${message}`);\r\n    }\r\n}\r\n\r\n\/\/ [\uc800\uc218\uc900 \ubaa8\ub4c8] \r\nclass KakaoTalkService implements MessageSender {\r\n    public sendMessage(message: string): void {\r\n        console.log(`[\uce74\uce74\uc624 API] \uc54c\ub9bc\ud1a1 \uc804\uc1a1: ${message}`);\r\n    }\r\n}\r\n\r\n\/\/ [\uace0\uc218\uc900 \ubaa8\ub4c8]\r\n\r\nclass NotificationService {\r\n    \/\/ \ud83d\udca1 \uad6c\uccb4\uc801\uc778 \ud074\ub798\uc2a4\uac00 \uc544\ub2cc, \ucd94\uc0c1\ud654\ub41c \uc778\ud130\ud398\uc774\uc2a4(MessageSender)\uc5d0\ub9cc \uc758\uc874\ud569\ub2c8\ub2e4.\r\n    private messageSender: MessageSender;\r\n\r\n    \/\/ \uc678\ubd80\uc5d0\uc11c \uc758\uc874\uc131\uc744 \uc8fc\uc785(Dependency Injection)\ubc1b\ub3c4\ub85d \uc124\uacc4\ud569\ub2c8\ub2e4.\r\n    constructor(messageSender: MessageSender) {\r\n        this.messageSender = messageSender;\r\n    }\r\n\r\n    public sendNotification(message: string): void {\r\n        this.messageSender.sendMessage(message);\r\n    }\r\n}\r\n\r\n\/\/ \ud074\ub77c\uc774\uc5b8\ud2b8 \uc0ac\uc6a9\r\n\r\nfunction run() {\r\n    \/\/ 1. \ub124\uc774\ubc84 SMS\ub97c \uc0ac\uc6a9\ud558\uace0 \uc2f6\uc744 \ub54c\r\n    const naverSms = new NaverSmsService();\r\n    const service1 = new NotificationService(naverSms);\r\n    service1.sendNotification(\"\uc548\ub155\ud558\uc138\uc694! \ub124\uc774\ubc84 SMS\uc785\ub2c8\ub2e4.\");\r\n\r\n    \/\/ 2. \uce74\uce74\uc624\ud1a1\uc73c\ub85c \uc218\ub2e8\uc744 \ubc14\uafb8\uace0 \uc2f6\uc744 \ub54c (NotificationService\uc758 \ucf54\ub4dc\ub294 \uc804\ud600 \ubcc0\uacbd \uc5c6\uc74c)\r\n    const kakaoTalk = new KakaoTalkService();\r\n    const service2 = new NotificationService(kakaoTalk);\r\n    service2.sendNotification(\"\uc548\ub155\ud558\uc138\uc694! \uce74\uce74\uc624\ud1a1 \uc54c\ub9bc\uc785\ub2c8\ub2e4.\");\r\n}\r\n\r\nrun();\r\n<\/pre>\n<p>\uc774 DIP \uc6d0\uce59\uc758 \uc7a5\uc810\uc744 \uc0dd\uac01\ud574 \ubcf4\uba74&#8230; \ube44\uc9c0\ub2c8\uc2a4 \ub85c\uc9c1(\uace0\uc218\uc900 \ubaa8\ub4c8)\uc758 \ubcc0\uacbd \uc5c6\uc774 \uc800\uc218\uc900 \ubaa8\ub4c8\uc744 \ubcc0\uacbd\ud558\uae30 \uc6a9\uc774\ud574 \uc9d1\ub2c8\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>SOLID\ub294 \uac1d\uccb4 \uc9c0\ud5a5 \ud504\ub85c\uadf8\ub798\ubc0d \ubc0f \uc124\uacc4(OOP)\uc5d0\uc11c \uc88b\uc740 \uc18c\ud504\ud2b8\uc6e8\uc5b4\ub97c \ub9cc\ub4e4\uae30 \uc704\ud574 \uc9c0\ucf1c\uc57c \ud558\ub294 5\uac00\uc9c0 \ud575\uc2ec \uc124\uacc4 \uc6d0\uce59\uc758 \uc55e \uae00\uc790\ub97c \ub534 \uc57d\uc5b4\uc785\ub2c8\ub2e4. \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4(Uncle Bob)\uc774 2000\ub144\ub300 \ucd08\ubc18\uc5d0 \uc815\ub9bd\ud55c \uc774 \uc6d0\uce59\ub4e4\uc758 \ud575\uc2ec \ubaa9\uc801\uc740, \uc2dc\uac04\uc774 \uc9c0\ub098\ub3c4 \uc720\uc9c0\ubcf4\uc218\uac00 \uc27d\uace0, \ud655\uc7a5\uc131\uc774 \ub192\uc73c\uba70, \ubcc0\ud654\uc5d0 \uc720\uc5f0\ud558\uac8c \ub300\ucc98\ud560 \uc218 \uc788\ub294 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uac83\uc785\ub2c8\ub2e4. SOLID\ub97c \uad6c\uc131\ud558\ub294 \uc6d0\uce59\uc740 SRP, OCP, LIP, ISP, DIP\uc785\ub2c8\ub2e4. SRP Single &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/www.gisdeveloper.co.kr\/?p=16884\" class=\"more-link\">\ub354 \ubcf4\uae30<span class=\"screen-reader-text\"> &#8220;SOLID&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-16884","post","type-post","status-publish","format-standard","hentry","category-design"],"_links":{"self":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/16884","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16884"}],"version-history":[{"count":6,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/16884\/revisions"}],"predecessor-version":[{"id":16890,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=\/wp\/v2\/posts\/16884\/revisions\/16890"}],"wp:attachment":[{"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16884"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16884"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.gisdeveloper.co.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16884"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}