๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ (OOP)

[OOP] ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„ ์›๋ฆฌ

loki d 2021. 8. 16. 16:20
728x90

๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„ ์›๋ฆฌ

1. SOLID

SOLID๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„ ์›๋ฆฌ ์ค‘ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋‹ค์„ฏ๊ฐ€์ง€ ์›๋ฆฌ SRP(Single Responsibility Principle), OCP(Open-Closed Principle), LSP(LIskov Substitution Principle), ISP(Interface Substitution Principle), DIP(Dependency Inversion Principle)๋ฅผ ๋งํ•œ๋‹ค.

1.1 SRP

๋‹จ์ผ ์ฑ…์ž„ ์›๋ฆฌ A class should have only one reason to change.

  • ์†Œํ”„ํŠธ์›จ์–ด์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ์„ค๊ณ„ ์›๋ฆฌ ์ค‘ ํ•˜๋‚˜๋Š” ๋ชจ๋“ˆ์€ ์‘์ง‘์„ฑ์ด ๋†’์•„์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. (high-cohesion) ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ๊ธฐ๋ณธ ๋ชจ๋“ˆ์€ ํด๋ž˜์Šค์ด๋‹ค. SRP์— ์˜ํ•˜๋ฉด ํ•œ ํด๋ž˜์Šค๋Š” ๋‹จ์ผ ์ฑ…์ž„์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.
  • ํ•œ ํด๋ž˜์Šค๋Š” ์ˆ˜์ •๋˜์–ด์•ผ ํ•  ์ด์œ ๊ฐ€ ํ•˜๋‚˜ ๋ฐ–์— ์—†์–ด์•ผ ํ•œ๋‹ค.
  • ํ•œ ํด๋ž˜์Šค๋Š” ์—ฌ๋Ÿฌ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ณ , ์—ฌ๋Ÿฌ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ SRP์— ์˜ํ•˜๋ฉด ์ด๋“ค์€ ๋ชจ๋‘ ๊ณตํ†ต์œผ๋กœ ํ•œ ๊ฐ€์ง€ ์ฑ…์ž„์„ ์œ„ํ•ด ํ•„์š”ํ•ด์•ผ ํ•œ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ์ง์›์ •๋ณด๋ฅผ ์œ ์ง€ํ•˜๋Š” Employee ํด๋ž˜์Šค์— ๊ธ‰์—ฌ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฉ”์†Œ๋“œ์™€ ์ง์› ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉด ์ด ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•  ์ด์œ ๋Š” ๋ช‡๊ฐ€์ง€์ธ๊ฐ€? ์ตœ์†Œ ๋‘๊ฐ€์ง€์ด๋‹ค.
  • ๊ธ‰์—ฌ๋ฅผ ์ธก์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ฐ”๋€Œ๋ฉด ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•˜๊ณ  + ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ ˆ์ฝ”๋“œ ๋ชจ์Šต์ด ๋ฐ”๋€Œ์–ด๋„ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค.
    • ๋ชจ๋“  ๊ฒƒ์€ ๊ทธ๊ฒƒ์˜ ์กด์žฌํ•  ์œ„์น˜๊ฐ€ ์žˆ๊ณ , ๋ชจ๋“  ๊ฒƒ์€ ์›๋ž˜ ์žˆ์–ด์•ผ ํ•  ๊ณณ์— ์žˆ์–ด์•ผ ํ•œ๋‹ค.
    • ํด๋ž˜์Šค๋ฅผ ์Šค์œ„์Šค ํฌ์ผ“ ๋‚˜์ดํ”„์ฒ˜๋Ÿผ ๋งŒ๋“ค๋ฉด ์•ˆ๋œ๋‹ค.
    • ํ•œ ๊ฐ€์ง€ ์ผ๋งŒ ํ•ด์•ผ ํ•˜๊ณ , ๊ทธ ์ผ์„ ์ž˜ ํ•ด์•ผ ํ•œ๋‹ค.
    • ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜์—ฌ ๊ทธ๊ฒƒ์„ ๊ผญ ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

1.2 OCP

์—ด๋ฆผ ๋‹ซํž˜ ์›๋ฆฌ Classes should be open for extension, but closed for modification.

  • OCP์— ์˜ํ•˜๋ฉด ํด๋ž˜์Šค๋Š” ํ™•์žฅ์— ๋Œ€ํ•ด์„œ ์—ด๋ ค ์žˆ์ง€๋งŒ ๋ณ€ํ™”์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํด๋ž˜์Šค๋Š” ์„ค๊ณ„ ํ›„ ๊ตฌํ˜„์ด ๋๋‚˜ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋ฉด ๋” ์ด์ƒ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์–ด์•ผ ํ•˜ใ…ใ„ด๋‹ค๋Š” ์ธก๋ฉด์—์„œ ๋‹ซ์„ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ๋‹ซ์€ ๊ฒฝ์šฐ์—๋„ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ํด๋ž˜์Šค๊ฐ€ ์ƒˆ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ•˜๋”๋ผ๋„ ์ด ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ๋‹ซํ˜€ ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.
    • ์ƒ์†์„ ํ™œ์šฉํ•จ -->> ์ƒ์†์€ is-a ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•ด์•ผ ํ•˜๋ฉฐ, ํด๋ž˜์Šค ๊ฐ„ ๊ด€๊ณ„๊ฐ€ ๊ณ ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์—ฐํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ํฌํ•จ๊ด€๊ณ„๋ฅผ ํ™œ์šฉํ•จ
  • ๋‹ซํ˜€ ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ๋” ์œ ์—ฐํ•˜๊ฒŒ ํ™•์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ํฌํ•จ ๊ด€๊ณ„๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ํด๋ž˜์Šค์˜ ์–ด๋–ค ๊ธฐ๋Šฅ์„ ๋‹ค๋ฅด ํด๋ž˜์Šค์— ์œ„์ž„ํ•˜๊ณ  ๊ทธ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์œ„ ํƒ€์ž… ๋ฉค๋ฒ„ ๋ณ€์ˆ˜์— ์œ ์ง€ํ•˜๋ฉด ์–ธ์ œ๋“ ์ง€ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ”๊พธ์–ด ๊ธฐ๋Šฅ์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ๋˜ ํฌํ•จ ๊ด€๊ณ„๋ฅผ ์ด์šฉํ•˜๋ฉด ๋‹ค์–‘ํ•œ ๊ฒƒ๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ํŠน์„ฑ์˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ๋Šฅํ™•์žฅ๊ณผ ๊ด€๋ จํ•˜์—ฌ ๋Š˜ ์ƒ๊ฐํ•ด์•ผ ํ•˜๋Š” ์„ค๊ณ„ ์›๋ฆฌ๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ณ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„๊ณผ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์›๋ฆฌ์™€ ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค ๋Œ€์‹ ์— ์ถ”์ƒ ํƒ€์ž…์— ์˜์กดํ•˜๋Š” ์›๋ฆฌ์ด๋‹ค.

1.3 LSP

๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›๋ฆฌ If S is a subtype of T, then objects of type T in a program may be replaced with objects of type S without altering any of the desirable properties of that program.
๊ฐ์ฒด์ง€ํ–ฅ์˜ ๊ฐ€์žฅ ํ•ต์‹ฌ ์š”์†Œ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์ƒ์†์ด๋‹ค. ์ƒ์†์€ ํ•œ ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ์‰ฝ๊ฒŒ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ํด๋ž˜์Šค P๋ฅผ ์ƒ์†ํ•˜์—ฌ ํด๋ž˜์Šค C๋ฅผ ์ •์˜ํ•˜๋ฉด ํด๋ž˜์Šค C๋Š” P์˜ ๋ชจ๋“  ์ƒํƒœ์™€ ํ–‰์œ„๋ฅผ ๋‹ค์‹œ ์ •์˜ํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.

  • ์ƒ์†์€ ์ฝ”๋“œ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๊ณ , ์ฝ”๋“œ ์ค‘๋ณต์„ ์—†์• ์ค€๋‹ค. ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋งŒ์ด ์ƒ์†์˜ ์žฅ์ ์€ ์•„๋‹ˆ๋‹ค. ์ƒ์†์€ ์ƒ์œ„ ํด๋ž˜์Šค ํƒ€์ž…์„ ํ›„์† ํด๋ž˜์Šค๋ฅผ ์•„์šฐ๋ฅด๋Š” ๊ณตํ†ต ๋ฆฌ๋ชจ์ปจ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ์ฆ‰ ์ƒ์œ„ ํƒ€์ž… ๋ณ€์ˆ˜์—๋Š” ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋‹คํ˜•์„ฑ์„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฒ”์šฉ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์ฝ”๋“œ ์žฌ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ๋ฌด์กฐ๊ฑด ์ƒ์†ํ•˜๋ฉด ๋งค์šฐ ์–ด์ƒ‰ํ•œ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์ƒ์†์€ ๋ฐ˜๋“œ์‹œ is-a ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. Pet ํด๋ž˜์Šค๊ฐ€ ์ด๋ฆ„์„ ์œ ์ง€ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•˜์—ฌ Pet์„ ์ƒ์†ํ•˜์—ฌ ์‚ฌ๋žŒ์„ ์ •์˜ํ•˜๋ฉด ์‚ฌ๋žŒ์€ ์• ์™„๋™๋ฌผ์ด๋‹ค ๋ผ๋Š” ๋ช…์ œ๊ฐ€ ์„ฑ๋ฆฝํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌ๋ฐ”๋ฅธ ์ƒ์† ๊ด€๊ณ„๋ผ ํ•  ์ˆ˜ ์—†๋‹ค.
  • ๊ฐ์ฒด์ง€ํ–ฅ์—์„œ๋Š” ํด๋ž˜์Šค๋‚˜ interface๋ฅผ ์ด์šฉํ•˜์—ฌ ์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ์ด์™€ ๊ด€๋ จํ•˜์—ฌ subclassing์ด๋ผ๋Š” ๊ฐœ๋…๊ณผ subtyping์ด๋ผ๋Š” ๊ฐœ๋…์ด ์žˆ๋‹ค.
    • subclassing : ํ•œ ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ
    • subtyping : ์™ธ๋ถ€ ๋ชจ์Šต๋งŒ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ
  • subcalssing ํ•˜๋ฉด subtyping์ด ๋ฌด์กฐ๊ฑด ์ œ๊ณต๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•˜์ง€๋งŒ LSP ์›๋ฆฌ์— ์˜ํ•˜๋ฉด subclassing๋„ subtyping์„ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค.
  • LSP๊ฐ€ ์œ„๋ฐฐ๋˜์ง€ ์•Š๋„๋ก ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ๋ฌธ๋ฒ•์ ์œผ๋กœ ๋‹ค์Œ์„ ๋ณด์žฅ
    • ๋ฉ”์†Œ๋“œ ์ธ์ž์˜ ๋ฐ˜๋ณ€์„ฑ(contravariance)
    • ๋ฉ”์†Œ๋“œ ๋ฐ˜ํ™˜ํƒ€์ž…์˜ ๊ณต๋ณ€์„ฑ(covariance)
  • ๊ณต๋ณ€์„ฑ์ด๋ž€ ์ž์‹ ํด๋ž˜์Šค์—์„œ ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ ํŠน์ • ํƒ€์ž…์ด ํŠน์ˆ˜ํ™”๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•˜๊ณ , ๋ฐ˜๋ณ€์„ฑ์€ ์žฌ์ •์˜ํ•˜๋ฉด์„œ ์ผ๋ฐ˜ํ™”๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•œ๋‹ค.
  • ๋ฉ”์†Œ๋“œ ์ธ์ž๋Š” ๋ณ€ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ์ผ๋ฐ˜ํ™”ํ™”๋ฉด ํƒ€์ž… ์•ˆ์ „์„ฑ์— ๋ฌธ์ œ๊ฐ€ ์—†์œผ๋ฉฐ, ๋ฉ”์†Œ๋“œ ๋ฐ˜ํ™˜ํƒ€์ž…์€ ๋ณ€ํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ํŠน์ˆ˜ํ™”ํ•˜๋ฉด ํƒ€์ž… ์•ˆ์ „์„ฑ์— ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค๊ฐ€ ์žˆ์„ ๋•Œ, CatShop์€ ๋ฉ”์†Œ๋“œ์˜ ์ธ์ž์™€ ๋ฐ˜ํ™˜ํƒ€์ž…์„ ๋ชจ๋‘ ํŠน์ˆ˜ํ™”ํ•˜์—ฌ ์žฌ์ •์˜ํ•˜ ์žˆ๊ณ , DogShop์€ ๋ฉ”์†Œ๋“œ์˜ ์ธ์ž์™€ ๋ฐ˜ํ™˜ํƒ€์ž…์„ ๋ชจ๋‘ ์ผ๋ฐ˜ํ™”ํ•˜์—ฌ ์žฌ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค.
  • class PetShot{ Pet getPet(){} void addPet(Pet pet){} } class CatShop extends PetShot{ Cat getPet(){} // ๊ณต๋ณ€์„ฑ O void addPet(Cat cat){} // ์žฌ์ •์˜๋กœ ์ธ์‹๋˜์ง€ ์•Š์Œ } class DogShop extends PetShot{ Object getPet(){} // ๋ฐ˜๋ณ€์„ฑ X void addPedt)Object pet){} // ์žฌ์ •์˜๋กœ ์ธ์‹ํ•˜์ง€ ์•Š์Œ ๋ฐ˜๋ณ€์„ฑ }
  • ์ž๋ฐ”๋Š” ๋ฉ”์†Œ๋“œ ๋ฐ˜ํ™˜ํƒ€์ž…์˜ ๊ณต๋ณ€์„ฑ์€ ์ง€์›ํ•˜์ง€๋งŒ ์ธ์ž์˜ ๋ฐ˜๋ณ€์„ฑ์€ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ž๋ฐ”๋Š” ์ธ์ž์˜ ๊ฒฝ์šฐ์—๋Š” ์ •ํ™•ํ•˜ ๊ฒŒ ์ผ์น˜ํ•˜์—ฌ์•ผ ํ•œ๋‹ค. C++๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค. C#์€ ๋ฉ”์†Œ๋“œ ๋ฐ˜ํ™˜ํƒ€์ž…์˜ ๊ณต๋ณ€์„ฑ๋„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ž๋ฐ”๋Š” checked ์˜ˆ์™ธ์˜ ๊ฒฝ์šฐ ์ž์‹์ด ๋” ๋งŽ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋ฌธ๋ฒ•์ ์œผ๋กœ ์˜ค๋ฅ˜๋ฅผ ์ฃผ๊ณ  ์žˆ์ง€๋งŒ ์˜ˆ์™ธ ๋ฐœ์ƒ์„ ๋ฌธ๋ฒ•์ ์œผ๋กœ ์—„๊ฒฉํ•˜๊ฒŒ ๊ฒ€์‚ฌํ•ด ์ฃผ๋Š” ์–ธ์–ด๋Š” ๊ฑฐ์˜ ์—†๋‹ค.
  • ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•  ๋•Œ ๋ฌธ๋ฒ•์ ์ธ ์ธก๋ฉด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋…ผ๋ฆฌ์  ์ธก๋ฉด๊นŒ์ง€ ๊ณ ๋ คํ•ด์•ผ LSP๊ฐ€ ์œ„๋ฐฐ๋˜์ง€ ์•Š๋Š”๋‹ค.
    • ๋ฉ”์†Œ๋“œ์˜ ์‚ฌ์ „ ์กฐ๊ฑด์€ ๊ฐ•ํ™”๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
    • ๋ฉ”์†Œ๋“œ์˜ ์‚ฌํ›„ ์กฐ๊ฑด์€ ์•ฝํ™”๋˜์ž ์•Š์•„์•ผ ํ•œ๋‹ค.
    • ์ƒ์œ„ ํƒ€์ž…์˜ ๋ถˆ๋ณ€ ์กฐ๊ฑด์€ ๊ณ„์† ์œ ์ง€๋˜์–ด์•ผ ํ•œ๋‹ค.
    • (ํžˆ์Šคํ† ๋ฆฌ ๊ทœ์น™) ๊ฐ์ฒด๋Š” ์ž์‹ ์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

1.4 ISP

์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›๋ฆฌ Clients should not be forced to depend upon interfaces that they do not use.

  • ISP ์›๋ฆฌ๋ž€ ํด๋ž˜์Šค๋Š” ์ž์‹ ์ด ํ•„์š”ํ•˜์ง€ ์•Š๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ๊ฐ•์š”๋˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค๋Š” ์›๋ฆฌ์ด๋‹ค. ์ด ์›๋ฆฌ์— ์ถฉ์‹คํ•˜๊ธฐ ์œ„ํ•ด ํด๋ž˜์Šค๋‚˜ interface๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์†Œ๋“œ์˜ ์ˆ˜๋Š” ์ตœ์†Œํ™”๋˜์–ด์•ผ ํ•œ๋‹ค. ์ƒ์†์€ ์ •์  ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์ƒ์†ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ทจ์‚ฌ ์„ ํƒํ•  ์ˆ˜ ์—†๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ๋นˆ ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•„์š” ์—†๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์ง€๋งŒ, ์ด ์›๋ฆฌ์— ์˜ํ•˜๋ฉด ์ด๊ฒƒ์€ ์ž˜๋ชป๋œ ์„ค๊ณ„์˜ ๊ฒฐ๊ณผ์— ํ•ด๋‹นํ•œ๋‹ค. ์ด ๋ฌธ์ œ๋Š” LSP ์ธก๋ฉด์—์„œ๋„ ์‚ดํŽด๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์„ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋ž˜์Šค๋ฅผ ์ •์˜
  • public interface LivingThing{ void eat(); void walk(); void swim(); void fly(); }
  • ์ง๊ด€์ ์œผ๋กœ ์‚ด์•„ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ๋‚ ์ง€ ๋ชปํ•˜๊ณ , ์ˆ˜์˜๋„ ๋ชปํ•˜๊ณ , ๋•…์—์„œ ๊ฑธ์„ ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์‰ฝ๊ฒŒ ์ž˜๋ชป ์ •์˜๋œ ๊ฒƒ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋“  ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์€ ๋จน์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— eat๋งŒ ์œ ์ง€ํ•˜๊ณ  ๋‹ค๋ฅธ 3๊ฐœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ชจ๋‘ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.
public interface LivingThing{
  void eat();
}

public interface LivingInSky extends LivingThing{
  void fly();
}

public interface LivingInWater extends LivingThing{
  void swim();
}

public interface LivingOnLand extends LivingThing{
  void walk();
}
  • ์˜ค๋ฆฌ, ๊ฐœ๊ตฌ๋ฆฌ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
public class Duck implements LivinInSky, LivinInWater, LivinOnLand{




}

public class Frog implements LivinInWater, LivinOnLand{

}
  • ISP๋ฅผ ๊ทน๋‹จ์ ์œผ๋กœ ์ ์šฉํ•˜๋ฉด ์œ„ ์˜ˆ์ฒ˜๋Ÿผ ๋‹จ์ผ ๋ฉ”์†Œ๋“œ interface๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ๋กœ ๋‹จ์ผ ๋ฉ”์†Œ๋“œ interface๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ISP๊ฐ€ ์œ„๋ฐฐ๋  ์ˆ˜ ์—†๋‹ค.
  • ํ•˜์ง€๋งŒ ํ•ญ์ƒ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด ์ž๋ฃŒ๊ตฌ์กฐ์™€ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด size, isEmpty ๋“ฑ์„ ํ•จ๊ป˜ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • public class Collection{ int size(); boolean isEmpty(): }
  • interface A์— f๋ผ๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•˜์ž. ์ด interface๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์—ฌ๋Ÿฌ ํด๋ž˜์Šค ์ค‘์— ๋Œ€๋‹ค์ˆ˜๊ฐ€ ๊ณตํ†ต์ ์œผ๋กœ g๋ผ๋Š” ๋ฉ”์†Œ๋“œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ํ•˜์ž. ๊ทธ๋Ÿฌ๋ฉด ISP์— ์˜ํ•˜๋ฉด ์ด๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์ผ๊นŒ? ์ด ๊ฒฝ์šฐ ํฌ๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ X๋Š” ์ƒˆ ๋ฉ”์†Œ๋“œ g๊ฐ€ ํ•„์š”ํ•œ ํด๋ž˜์Šค์ด๊ณ , Y๋Š” g๊ฐ€ ํ•„์š”์—†๋Š” ๊ธฐ์กด A๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋Š” ํด๋ž˜์Šค๋ผ ํ•˜์ž.
    • ๋ฐฉ๋ฒ•1. A์— g๋ฅผ ์ถ”๊ฐ€ํ•จ. X๋Š” ์ž์‹ ์— ๋งž๊ฒŒ g๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•จ. Y๋Š” g๋ฅผ ๋นˆ ๋ฉ”์†Œ๋“œ๋กœ ์žฌ์ •์˜ํ•˜์—ฌ ๋ฌธ์ œ๊ฐ€ ์—†๋„๋ก ํ•จ
    • ๋ฐฉ๋ฒ• 2. A๋ฅผ ์ƒ์†ํ•˜๋Š” ์ƒˆ interface B๋ฅผ ์ •์˜ํ•˜๊ณ  B์— g๋ฅผ ์„ ์–ธํ•จ. X๋Š” interface B๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก ์ˆ˜์ •ํ•˜๊ณ  ์ž์‹ ์— ๋งž๊ฒŒ g๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ , Y๋Š” ์ˆ˜์ • ์—†์ด ์‚ฌ์šฉํ•จ
    • ๋ฐฉ๋ฒ• 3. ์ƒˆ interface B๋ฅผ ์ •์˜ํ•˜๊ณ  B์— g๋ฅผ ์„ ์–ธํ•จ. lstinlineX๋Š” interface B๋ฅผ ์ถ”๊ฐ€ ๊ตฌํ˜„ํ•˜๋„๋ก ์ˆ˜์ •ํ•˜๊ณ  ์ž์‹ ์— ๋งž๊ฒŒ g๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์‚ฌ์šฉํ•จ. lstinlineY๋Š” ์ˆ˜์ • ์—†์ด ์‚ฌ์šฉํ•จ
  • ์ž๋ฐ” 8 ์ดํ›„์—๋Š” ๋ฐฉ๋ฒ• 1์„ ์‚ฌ์šฉํ•  ๋•Œ g๋ฅผ ์„ ์–ธ๋งŒ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋กœ ๊ธฐ๋ณธ ๋นˆ ๋ฉ”์†Œ๋“œ๋กœ ์ •์˜ํ•˜๋ฉด ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๊ณผ ๋งˆ์ฐฌ๊ฐ€ ์ง€๋กœ Y๋Š” ์ˆ˜์ • ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1.5 DIP

์˜์กด๊ด€๊ณ„ ๋’ค์ง‘๊ธฐ ์›๋ฆฌ Depend upon abstractions. Do not depend on concrete classes.

  • ํ•œ ํด๋ž˜์Šค A๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ๋‹ค๋ฅธ ํด๋ž˜์Šค B๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด A๋Š” B์— ์˜์กดํ•œ๋‹ค๊ณ  ๋งํ•œ๋‹ค. ๋‘˜ ๊ฐ„ ๊ด€๊ณ„๊ฐ€ ์ƒ์†๊ณผ ๊ฐ™์ด ์ •์ ์ธ์ง€ ๋™์ ์ธ์ง€ ์ƒ๊ด€์—†์ด ๋‘ ํด๋ž˜์Šค ๊ฐ„ ๋˜๋Š” ๋‘ ํด๋ž˜์Šค ๊ฐ์ฒด ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋˜๋ฉด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋Š” ๋‹ค๋ฅธ ํ•˜๋‚˜๋ฅผ ์˜์กด ํ•œ๋‹ค๊ณ  ๋งํ•œ๋‹ค. ํ•œ ๋ชจ๋“ˆ์˜ ๊ฒฐํ•ฉ์„ฑ์€ ๋‚ฎ์„์ˆ˜๋ก(low-coupling) ํšจ๊ณผ์ ์ด๋ผ๋Š” ์›๋ฆฌ ๋งค์šฐ ์˜ค๋ž˜๋œ ์†Œํ”„ํŠธ์›จ์–ด ์›๋ฆฌ์ด๋‹ค. ์ฆ‰, ์˜์กด๊ด€๊ณ„๊ฐ€ ์ ์„์ˆ˜๋ก ํšจ๊ณผ์ ์ด๋‹ค.
  • DIP ์›๋ฆฌ๋Š” ์˜์กด์„ ํ•˜๋”๋ผ๋„ ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค ๋Œ€์‹ ์— ์ƒ์œ„ ์ถ”์ƒ ํƒ€์ž…์ด๋‚˜ interface ์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค๋Š” ์›๋ฆฌ ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์›๋ฆฌ์— ์ถฉ์‹คํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฆฌํŽ™ํ† ๋ง์ด ํ•„์š”ํ•˜๋‹ค.
    • ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์ด ์žˆ์œผ๋ฉด ๊ฐ„์ ‘ ์ฐธ์กฐํ•˜๋„๋ก ๋ฐ”๊พธ์–ด์•ผ ํ•œ๋‹ค.
    • ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์˜ ํ–‰์œ„๋“ค์„ ์ถ”์ƒ ํด๋ž˜์Šค๋‚˜ interface๋กœ ์ผ๋ฐ˜ํ™”ํ•ด์•ผ ํ•œ๋‹ค.
    • ์ƒ์† ๋Œ€์‹ ์— ํฌํ•จ ๊ด€๊ณ„๋ฅผ ํ™œ์šฉํ•˜์—ฌ์•ผ ํ•œ๋‹ค.
public class OrderFood{
  private Baemin finder = new Bamin();
  public List<Restaurant> getRestaurantByType(FoodType type){
    return finder.findAll(type);
    }
 }
  • ์ด ์˜ˆ์—์„œ๋Š” OrderFood ํด๋ž˜์Šค๋Š” Baemin์ด๋ผ๋Š” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ ํด๋ž˜์Šค ๊ด€๊ณ„๋„์—์„œ ํ™”์‚ดํ‘œ๊ฐ€ OrderFood์—์„œ Baemin ๋ฐฉํ–ฅ์œผ๋กœ ํ–ฅํ•˜๊ฒŒ ๊ทธ๋ฆฌ๊ฒŒ ๋œ๋‹ค.
  • ๋‹ค์Œ๊ณผ ๊ฐ™์€ interface๋ฅผ ์ •์˜
public interface FoodDeliveryFinder{
  List<Restaurant> findAll(FoodType type);
}
  • interface๋ฅผ ๊ตฌํ˜„ํ•˜๋„๋ก Baemin์„ ์ˆ˜์ •ํ•˜๊ณ , OrderFood ํด๋ž˜์Šค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์˜€๋‹ค๊ณ  ํ•˜์ž.
public class OrderFood{
  private FoodDeliveryFinder finder = null;
  public OrderFood(FoodDeliverlyFinder finder){
     this.finder = Objects.requireNonNull(finder);
   }

   public void setFoodDeliveryFInder(FoodDeliverlyFInder finder){
     this.finder = objects.requireNonNull(finder);
   }

   public List<Restaurant> getREstaurantByType(FoodType type){
     return finder.findAll(type);
   }
 }
  • OrderFood ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•œ๋‹ค๊ณ  ๊ฐ€์ •
  • OderFood orderFood = new OrderFood(new Baemin());
  • ์ด์ฒ˜๋Ÿผ ์ˆ˜์ •์„ ํ•˜๋ฉด OrderFood๋Š” ๊ถ๊ทน์—๋Š” Baemin ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ OrderFood๋Š” Baemin์— ๋” ์ด์ƒ ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค. ํด๋ž˜์Šค ๊ด€๊ณ„๋„๋ฅผ ๊ทธ๋ ค๋„ OrderFood์™€ Baemin ๊ฐ„์— ํ™”์‚ดํ‘œ๊ฐ€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š๋Š”๋‹ค. ์ด ์ธก๋ฉด์—์„œ ์˜์กด๊ด€๊ณ„ ๋’ค์ง‘๊ธฐ๋ผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
  • ์˜์กด๊ด€๊ณ„๋ฅผ ๋’ค์ง‘๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„๊ณผ ์–ธ์ œํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•ด์•ผ ํ•˜๊ณ , ์–ธ์ œํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„๊ณผ ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„์€ ์„œ๋กœ ๋ชจ๋ฅด๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค. ์ด ์˜ˆ์—์„œ ์Œ์‹์ ์„ ์ฐพ๋Š” how๋Š” Baemin์ด ๋‹ด๋‹นํ•˜์ง€๋งŒ ์–ธ์ œ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ• ์ง€๋Š” OrderFood ํด๋ž˜์Šค๊ฐ€ ๊ฒฐ์ •ํ•˜์ง€๋งŒ ์„œ๋กœ ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ด์™€ ๊ฐ™์ด ๊ด€๊ณ„๋ฅผ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ๋•Œ ๊ณ ์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ด€๊ณ„๋ฅผ ๋งบ์„ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ๊ด€๊ณ„ ์ฃผ์ž…(dependency injection)์ด๋ผ ํ•œ๋‹ค.
  • ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„๊ณผ ์–ธ์ œํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ์˜ˆ๋กœ GUI์—์„œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ์™€ interface๋ฅผ ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ์˜ ๊ฒฝ์šฐ ์ฒ˜๋ฆฌ์ž๊ฐ€ ๋ฌด์—‡์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„์ด๊ณ , ์‚ฌ๊ฑด ๋ฐœ์ƒ์ด ์–ธ์ œํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค. ์ฆ‰, interface๋Š” what๊ณผ how๋ฅผ ๋ถ„๋ฆฌํ•ด ์ฃผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด how์™€ when๋„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. interface๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค๊ฐ€ ์–ด๋–ป๊ฒŒ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋ฉฐ, ์ด interface๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ธก์ด ์–ธ์ œํ•  ๊ฒƒ์ธ์ง€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.
  • ๊ด€๊ณ„ ์ฃผ์ž…์ด ์˜์กด๊ด€๊ณ„๋ฅผ ๋’ค์ง‘๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค. ์ƒ์† ๊ด€๊ณ„์—์„œ๋„ ์ž์‹ ํด๋ž˜์Šค์— ํ–‰์œ„ ๊ตฌํ˜„์˜ ์ผ๋ถ€๋ฅผ ์œ„์ž„ํ•˜์ง€๋งŒ ์–ด๋–ค ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์˜ฌ์ง€ ๋ถ€๋ชจ ํด๋ž˜์Šค๋Š” ๋ชจ๋ฅด๋Š” ์ƒํƒœ์—์„œ ๋ถ€๋ชจ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
public class Person{
  private String naem;
  prvate Pet pet;
  public void setPet(Pet pet){
    this.pet = pet;
    }
  }

์˜์กด๊ด€๊ณ„ ์ฃผ์ž…

  • OCP๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ๋„๋ฆฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋Š” ํฌํ•จ ๊ด€๊ณ„๋ฅผ ๋ชจ๋ธ๋งํ•  ๋•Œ ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค ํƒ€์ž…์„ ์ด์šฉ ํ•˜์—ฌ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ์ƒ์† ๊ด€๊ณ„๋‚˜ ๊ตฌ์ฒดํ™” ๊ด€๊ณ„์—์„œ ์ƒ์œ„ ํƒ€์ž…์„ ์ด์šฉํ•˜์—ฌ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ทธ๋ฆผ 1.1์™€ ๊ฐ™์ด ์‚ฌ๋žŒ๊ณผ ๊ทธ ์‚ฌ๋žŒ์ด ๊ธฐ๋ฅด๋Š” ์• ์™„๋™๋ฌผ์„ ๋ชจ๋ธ๋งํ•˜๊ธฐ ์œ„ํ•ด Person ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋ฉด์„œ Pet ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์ƒ์†๊ณ„์ธต๋„์—์„œ ๋‹จ๋ง์— ํ•ด๋‹นํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ํด๋ž˜์Šค์ธ Siamese๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์€ ํฐ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.
  • ์ „์ž๋Š” ๋‹ค์–‘ํ•œ ์• ์™„๋™๋ฌผ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ณ  ์‹ฌ์ง€์–ด ๋‚˜์ค‘์— ์ƒˆ๋กœ์šด ์• ์™„๋™๋ฌผ์„ ์ •์˜ํ•˜๋”๋ผ๋„ ์ด ์• ์™„๋™๋ฌผ์˜ ์กฐ์ƒ ํด๋ž˜์Šค๊ฐ€ Pet์ด๋ฉด Person ํด๋ž˜์Šค๋ฅผ ์žฌ์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋”๋ผ๋„ Person ๊ฐ์ฒด๋Š” ์ด ์ƒˆ ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, Pet ์•„๋ž˜์— ์ˆ˜ ๋งŽ์€ ํด๋ž˜์Šค๋“ค์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ Person์€ ์ด๋“ค์— ๋Œ€ํ•œ ์ง€์‹์—†์ด ์ด๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๋Š” ํŠน์ •ํ•œ ์ข…๋ฅ˜์˜ ์• ์™„๋™๋ฌผ๊ณผ ๊ด€๊ณ„๋ฅผ ๋งบ๊ฒŒ ๋œ๋‹ค.
p.setPet(new SiberianHusky());

๊ธฐํƒ€ ์›๋ฆฌ

1. ๋ณ€ํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ๋ถ€๋ถ„์„ ์ถ”์ƒํ™”ํ•ด๋ผ

  • ๋ณ€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์€ ํ–ฅํ›„ ํ™•์žฅ์„ ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. OCP์™€ ๋งค์šฐ ๋ฐ€์ ‘ํ•œ ๊ด€๋ จ์ด ์žˆ๋Š” ์›๋ฆฌ์ด๋‹ค. ์ด ์›๋ฆฌ๋Š” ๊ฐ์ฒด์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋Š˜ ์ ์šฉํ•ด์•ผ ํ•˜๋Š” ์›๋ฆฌ์ด๋‹ค.2. ๊ตฌ์ฒด์  ํƒ€์ž…์— ์˜์กดํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ถ”์ƒ ํƒ€์ž…์— ์˜์กดํ•ด๋ผ
  • ๊ตฌ์ฒด์  ํƒ€์ž…์— ์˜์กดํ•˜๋ฉด ์œ ์—ฐ์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜๋ฐ–์— ์—†๋‹ค. ๋ฐ˜๋ฉด์— ์ถ”์ƒ ํƒ€์ž…์— ์˜์กดํ•˜๋ฉด ์‹ค์ œ ๊ด€๊ณ„๋ฅผ ๋งบ๋Š” ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์€ ์ฝ”๋“œ ์ˆ˜์ •์—†์ด ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฏธ๋ž˜์— ๊ตฌํ˜„ํ•  ๊ฐ์ฒด์™€๋„ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.3. ๋А์Šจํ•œ ์—ฐ๊ฒฐ์„ ์„ ํ˜ธํ•ด๋ผ
  • ์„œ๋กœ ์ƒํ˜ธ์ž‘์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฐ์ฒด ๊ฐ„์—๋Š” ๋А์Šจํ•œ ์—ฐ๊ฒฐ์„ ์„ ํ˜ธํ•˜๋ผ๋Š” ๊ฒƒ์€ ๊ตฌ์ฒด์  ํƒ€์ž… ๋Œ€์‹ ์— ์ถ”์ƒ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜ ๋ผ๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค. ํ•œ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฒƒ์ด ๋งŽ์œผ๋ฉด ๋งŽ์„์ˆ˜๋ก ๊ฐ•ํ•œ ์—ฐ๊ฒฐ์ด๋ผ ํ•œ๋‹ค.4. ์ตœ์†Œ ์ง€์‹ ์›๋ฆฌ
  • ์ด ์›๋ฆฌ์™€ ๋ฐ€์ ‘ํ•œ ๊ด€๋ จ์ด ์žˆ๋Š” ์›๋ฆฌ๊ฐ€ ๋ฐ๋ฉ”ํ…Œ๋ฅด ๊ทœ์น™(law of demeter)์ด๋‹ค. ๋ฐ๋ฉ”ํ…Œ๋ฅด ๊ทœ์น™์€ ๋‹ค์Œ 4๊ฐ€์ง€ ๊ทœ์น™์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค.
    • ๊ทœ์น™ 1. ํด๋ž˜์Šค O์— ์ •์˜๋˜์–ด ์žˆ๋Š” ๋ฉ”์†Œ๋“œm์€ ํด๋ž˜์Šค O์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฉ”์†Œ๋“œ๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ทœ์น™ 2. ๋ฉ”์†Œ๋“œm์€ ๊ทธ๊ฒƒ์˜ ์ธ์ž๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ทœ์น™ 3. ๋ฉ”์†Œ๋“œm ๋‚ด์—์„œ ์–ด๋–ค ๊ฐ์ฒด o๋ฅผ ์ƒ์„ฑํ•˜์˜€์œผ๋ฉด ๊ทธ ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ทœ์น™ 4. ํด๋ž˜์Šค O์— ์ •์˜๋˜์–ด ์žˆ๋Š” ๋ฉ”์†Œ๋“œ m์€ O์˜ ๋ฉค๋ฒ„ ๋ณ€์ˆ˜ ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
class A{
  public void foo(){}
}

class B{
  public void bar(){}
}

class C{
  public void baz(){}
}

class D{
  private A a = new A();
  public void ham(C c){
    B b = new B();
    egg();                 // rule1
    c.baz();               // rule2
    b.bar();               // rule3
    a.foo();               // rule4
   }
   public void egg(){}
}

5. ์ƒ์† ๊ด€๊ณ„๋ณด๋‹ค ํฌํ•จ ๊ด€๊ณ„๋ฅผ ์„ ํ˜ธํ•ด๋ผ

  • ์ƒ์† ๊ด€๊ณ„๋Š” ํด๋ž˜์Šค ๊ฐ„ ๊ด€๊ณ„์ด๋ฉฐ, ์ •์  ๊ด€๊ณ„์ด๋‹ค. ์ƒ์†์€ is-a ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•  ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋ฉฐ, is-a ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•˜๋”๋ผ๋„ LSP์— ์œ„๋ฐฐ๋˜์ง€ ์•Š๋Š”์ง€ ๊ฒ€ํ† ํ•ด์•ผ ํ•œ๋‹ค. ์ƒ์†์€ ์ •์  ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋˜๋ฉด ์ฝ”๋“œ ์ˆ˜์ • ์—†์ด๋Š” ๊ด€๊ณ„๋Š” ์ง€์†๋œ๋‹ค. ์ด ๋•Œ๋ฌธ์— ๋” ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์— ํ•ด๋‹นํ•˜๋Š” ๊ด€๊ณ„์ด๋‹ค. ๋ฐ˜๋ฉด์— ํฌํ•จ ๊ด€๊ณ„๋Š” ๊ฐ์ฒด ๊ฐ„ ๊ด€๊ณ„์ด๋ฉฐ ๋™์  ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— ๋” ์œ ์—ฐํ•˜๋‹ค. ์ด๋•Œ ์ค‘์š”ํ•œ ๊ฒƒ์€ DIP ์›๋ฆฌ์— ๋”ฐ๋ผ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ด€๊ณ„๋ฅผ ํ˜•์„ฑํ•˜๋ฉด ์•ˆ ๋œ๋‹ค. ํ•œ ๊ฐ์ฒด๋Š” ์ถ”์ƒ ํƒ€์ž…์˜ ๋ณ€์ˆ˜๋‚˜ interface ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‹คํ–‰ ์‹œ๊ฐ„์— ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ”๊พธ์–ด ๊ธฐ๋Šฅ์„ ๋™์ ์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ํฌํ•จ ๊ด€๊ณ„๋Š” ๋А์Šจํ•œ ๊ฒฐํ•ฉ์— ํ•ด๋‹นํ•˜๋Š” ๊ด€๊ณ„์ด๋‹ค.
  • ํ•˜์ง€๋งŒ ์ด ์›๋ฆฌ์— ๋”ฐ๋ผ ์ƒ์†์„ ์ ˆ๋Œ€ ์•…์œผ๋กœ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์€ ์ž˜๋ชป๋œ ๊ฒƒ์ด๋‹ค. ์ƒ์†์œผ๋กœ ๋ชจ๋ธ๋งํ•ด์•ผ ํ•  ๊ฒฝ์šฐ๋„ ์žˆ๊ณ  ์ƒ์† ๋Œ€์‹ ์— ํฌํ•จ ๊ด€๊ณ„๋กœ ๋ชจ๋ธ๋งํ•ด์•ผ ํ•  ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ํŠนํžˆ, ํฌํ•จ ๊ด€๊ณ„๋งŒ์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒ์†์ฒ˜๋Ÿผ ์ฝ”๋“œ ์ค‘๋ณต์„ ํšจ๊ณผ์  ์œผ๋กœ ์ œ๊ฑฐํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœํ•˜๊ณ ์ž ์‘์šฉ์—์„œ ํ•„์š”ํ•œ ๊ฒƒ์ด ๋ฌด์—‡์ธ์ง€ ์ž˜ ์‚ดํŽด๋ณด์•„์•ผ ํ•˜๋ฉฐ, ์–ด๋–ค ๊ด€๊ณ„๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ๊ณผ์ ์ธ์ง€ ์ž˜ ์‚ดํŽด๋ณด์•„์•ผ ํ•œ๋‹ค. ํด๋ž˜์Šค ๊ฐ„์— is-a์™€ ๊ฐ™์€ ๋…ผ๋ฆฌ์  ๊ด€๊ณ„๊ฐ€ ํ˜•์„ฑ๋˜๋Š”์ง€, ํด๋ž˜์Šค ๊ฐ„์— ๊ณตํ†ต๋œ ํ–‰์œ„๊ฐ€ ๋ฌด์—‡์ธ์ง€. ๊ฐ™์€ ํ–‰์œ„์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋‹ค๋ฅธ ๊ตฌํ˜„์ด ํ•„์š”ํ•œ ๊ฒƒ์ธ์ง€ ๋“ฑ์„ ๊ฐœ๋ฐœํ•˜๊ณ ์ž ํ•˜๋Š” ์‘์šฉ์— ๋Œ€ํ•ด ๊ฒ€ํ† ํ•ด ๋ณด์•„์•ผ ํ•œ๋‹ค.6. ํ• ๋ฆฌ์šฐ๋“œ ์›์น™
  • ์ƒ์œ„ ์ˆ˜์ค€ ์š”์†Œ๊ฐ€ ํ•˜์œ„ ์ˆ˜์ค€ ์š”์†Œ์— ์˜์กดํ•˜๊ณ  ์ด ํ•˜์œ„ ์ˆ˜์ค€ ์š”์†Œ๊ฐ€ ๋‹ค์‹œ ์ƒ์œ„ ์ˆ˜์ค€ ์š”์†Œ์— ์˜์กดํ•˜๊ณ , ๊ทธ ์ƒ์œ„ ์ˆ˜์ค€ ์š”์†Œ๊ฐ€ ๋˜ ๋‹ค๋ฅธ ์š”์†Œ์— ์˜์กดํ•˜๋Š” ๋“ฑ ์˜์กด ๊ด€๊ณ„๊ฐ€ ๋ณต์žกํ•˜๊ณ  ๊ผฌ์—ฌ ์žˆ๋Š” ๊ฒฝ์šฐ์— ์˜์กด์„ฑ ๋ถ€ํŒจ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  ๋งํ•œ๋‹ค. ์ด์ฒ˜๋Ÿผ ์˜์กด ๊ด€๊ณ„๊ฐ€ ๋ณต์žกํ•˜๊ฒŒ ๊ผฌ์ด์ง€ ์•Š๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์„ค๊ณ„ ์›์น™ ์ค‘ ํ•˜๋‚˜๊ฐ€ ํ• ๋ฆฌ์šฐ๋“œ ์›์น™์ด๋‹ค. ์ด ์›์น™์— ์˜ํ•˜๋ฉด ํ•˜์œ„ ์ˆ˜์ค€ ์š”์†Œ๋Š” ์ƒ์œ„ ์ˆ˜์ค€ ์š”์†Œ์™€ ์—ฐ๊ฒฐ๋˜์–ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ƒ์œ„ ์ˆ˜์ค€ ์š”์†Œ๊ฐ€ ์–ธ์ œ ์–ด๋–ป๊ฒŒ ํ•˜์œ„ ์ˆ˜์ค€ ์š”์†Œ๋ฅผ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜๋ฉฐ, ํ•˜์œ„ ์ˆ˜์ค€ ์š”์†Œ๋Š” ์ ˆ๋Œ€ ์ƒ์œ„ ์ˆ˜์ค€ ์š”์†Œ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
  • ํ• ๋ฆฌ์šฐ๋“œ ์›์น™์€ ์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™๊ณผ ๋น„๊ตํ•˜์—ฌ ๋ณด๋ฉด ์˜์กด์„ฑ ๋’ค์ง‘๊ธฐ ์›์น™์ด ๋” ํฌ๊ด„์ ์ธ ๊ฐœ๋…์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค. ํ• ๋ฆฌ์šฐ๋“œ ์›์น™์€ ์ƒ์† ๊ด€๊ณ„์™€ ๊ด€๋ จ๋œ ์›๋ฆฌ์ด์ง€๋งŒ DIP๋Š” ๊ด€๊ณ„ ์ฃผ์ž… ๋“ฑ ์ƒ์†, ํฌํ•จ ๊ด€๊ณ„ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ํ†ตํ•ด ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์›๋ฆฌ์ด๋‹ค.