0822 ~ 0911


# 0822 ~ 0911

# 0823 - ELK

# ELK๋ž€?

ELK๋Š” Elasticsearch, Logstash, Kibana์˜ ์•ž๊ธ€์ž๋ฅผ ๋”ฐ์™€์„œ ๋งŒ๋“  ์•ฝ์–ด์ด๋‹ค.

  • Elasticsearch๋Š” ๊ฒ€์ƒ‰ ๋ฐ ๋ถ„์„ ์—”์ง„
  • Logstash๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜์—ฌ ๋ณ€ํ™˜ ํ›„ Elastic search๊ฐ™์€ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ
  • Kibana๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•˜์—ฌ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
    ์ฆ‰, ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•ด ์‹œ๊ฐํ™” ํ•˜๋Š” ์˜คํ”ˆ์†Œ์Šค

ELK๋Š” ์˜คํ”ˆ์†Œ์Šค๋กœ, ๋ฌด๋ฃŒ๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
ํด๋ผ์šฐ๋“œ ๊ฐ™์ด ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ์„œ๋ฒ„๋Š” ๋กœ๊ทธ๊ฐ€ ๋งŽ์•„ ๋ถ„์„ํ•˜๋Š”๋ฐ ์–ด๋ ค์›€์ด ์กด์žฌํ•˜๋Š”๋ฐ, ๋กœ๊ทธ ํŒŒ์ผ์˜ ์šฉ๋Ÿ‰์ด ์ปค์ ธ ๋””์Šคํฌ ๊ณต๊ฐ„์ด ๋ถ€์กฑํ•˜๊ฑฐ๋‚˜, ํŠน์ • ๋กœ๊ทธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ์—” ๋„ˆ๋ฌด ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์•„ ์ฐพ๊ธฐ ์–ด๋ ค์šด ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
๊ทธ๋ž˜์„œ ELK๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ์˜ ๋ถ„์„ ๋ฐ ๊ฒ€์ƒ‰์„ ํšจ์œจ์ ์œผ๋กœ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค. ใ…‡์—ฌ๊ธฐ์— ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘์„ ํ•˜๋Š” Filebeat๊ฐ€ ์ถ”๊ฐ€๋˜๋ฉด์„œ ELK Stack์œผ๋กœ ๋ถˆ๋ฆฌ๊ฒŒ ๋˜์—ˆ๋‹ค.

# ELK Stack

  • Apache Lucene ๊ธฐ๋ฐ˜์˜ Java ์˜คํ”ˆ์†Œ์Šค ๋ถ„์‚ฐ ๊ฒ€์ƒ‰์—”์ง„.
  • Elasticsearch๋Š” Logstash๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ƒ‰ ๋ฐ ๋ถ„์„ํ•˜์—ฌ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์–ป์„์ˆ˜ ์žˆ๋‹ค.
  • ์–ผ๋งˆ๋‚˜ ๋น ๋ฅด๋ƒ๋ฉด 10๋…„์น˜ ๋ฐ์ดํ„ฐ๋ฅผ OracleDB์—์„œ ๊ฒ€์ƒ‰ํ•˜๋ฉด 1๋‹ฌ์ •๋„ ๊ธฐ๋‹ค๋ ค์•ผ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, Elasticsearch๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒ€์ƒ‰ํ•˜๋‹ˆ ๊ฒฐ๊ณผ๊ฐ€ ๋‹จ ๋ช‡๋ถ„๋งŒ์— ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

# 2. Logstash

  • scv, DB ๋“ฑ ๋‹ค์–‘ํ•œ ์†Œ์Šค์—์„œ ๋กœ๊ทธ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘, ์ง‘๊ณ„, ํŒŒ์‹ฑํ•˜์—ฌ Elasticsearch๋กœ ์ „๋‹ฌ.
  • ์„œ๋ฒ„์ธก ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„ ๋ผ์ธ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์—”์ง„์ด๋‹ค.

# 3. Kibana

  • Elasticsearch์™€ ํ•จ๊ป˜ ๋™์ž‘ํ•˜๋„๋ก ์„ค๊ผ๋œ ์˜คํ”ˆ์†Œ์Šค ๋ถ„์„ ๋ฐ ์‹œ๊ฐํ™” ํ”Œ๋žซํผ.
  • ํžˆ์Šคํ† ๊ทธ๋žจ, ์„ ํ˜• ๊ทธ๋ž˜ํ”„, ์›ํ˜• ์ฐจํŠธ ๋“ฑ ๋‹ค์–‘ํ•œ ์ฐจํŠธ ๋ฐ ๋ถ„์„์— ๋Œ€ํ•ด ์‹œ๊ฐํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณต.

# 4. Filebeat

  • ์„œ๋ฒ„์— ์—์ด์ „ํŠธ๋กœ ์„ค์น˜ํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ๋ฐ์ดํ„ฐ๋ฅผ Elasticsearch ๋˜๋Š” Logstash์— ์ „์†กํ•˜๋Š” ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์ž์ด๋‹ค.
  • Filebeat์€๋กœ๊ทธ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์ •ํ•˜๋Š” inputs๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ, ์—ฌ๊ธฐ์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค ์ˆ˜์ง‘ํ•˜์—ฌ ์ „์†ก.

# 0829 - MockMvc vs Restassured

# MockMvc

# ์‚ฌ์šฉ๋ชฉ์ 

MockMvc๋Š” ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์— ๋ฐฐํฌํ•˜์ง€ ์•Š๊ณ ๋„ ์Šคํ”„๋ง MVC์˜ ๋™์ž‘์„ ์žฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ ๋Œ€๋ถ€๋ถ„ Controller Layer Unit Test(๋‹จ์œ„ ํ…Œ์ŠคํŠธ)์— ์‚ฌ์šฉ๋œ๋‹ค.

์‹ค์ œ ์„œ๋ฒ„ ํ™˜๊ฒฝ๊ณผ ๋™์ผํ•œ @SpringBootTest๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฏ€๋กœ @WebMvcTest๋ฅผ ํ†ตํ•ด Presentation Layer Bean๋“ค๋งŒ ๋ถˆ๋กœ์˜จ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์™ธ Bean์€ Mock ๊ฐ์ฒด ์„ค์ •์„ ํ•ด์ฃผ์–ด ์ˆœ์ˆ˜ํ•œ Controller ๋กœ์ง์„ ํ…Œ์ŠคํŠธํ•œ๋‹ค.

# ์˜์กด์„ฑ

MockMvc๋Š” Spring Framework Test ํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜๋‹ค. ์ฆ‰ Spring test ์˜์กด์„ฑ์ด ์ถ”๊ฐ€๋˜์–ด์žˆ๋Š” ๊ฒฝ์šฐ ๋ณ„๋„์˜ ์˜์กด์„ฑ ์ถ”๊ฐ€๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

# ์†๋„

MockMvc๋Š” ๋ณ„๋„์˜ ๊ตฌ์„ฑ์—†์ด๋„ @WebMvcTest๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฌผ๋ก  @SpringBootTest๋กœ๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. MockMvc๋ฅผ @WebMvcTest๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

@WebMvcTest
@AutoConfigureMockMvc
public class ApiTest {
    @Autowired
    private MockMvc mockMvc;
    ...
}

# ๊ฐ€๋…์„ฑ

@Test
public void getMember() throws Exception {
    mockMvc.perform(get("/members/1")
            .accept(MediaType.APPLICATION_JSON))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.id", Matchers.is(1)))
}

# RestAssured

# ์‚ฌ์šฉ๋ชฉ์ 

RestAssured๋Š” REST ์›น ์„œ๋น„์Šค๋ฅผ ๊ฒ์ฆํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋ฉฐ ๋Œ€๋ถ€๋ถ„ End-to-End Test(์ „ ๊ตฌ๊ฐ„ ํ…Œ์ŠคํŠธ)์— ์‚ฌ์šฉ๋œ๋‹ค.

@SpringBootTest๋กœ ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด์„œ ์ „์ฒด์ ์ธ ๋กœ์ง์„ ํ…Œ์ŠคํŠธํ•œ๋‹ค. ์‹ค์ œ ์š”์ฒญ์‹œ ํ•„์š”ํ•œ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋„ ์ œ๊ณตํ•œ๋‹ค.

# ์˜์กด์„ฑ

RestAssured๋Š” ์ง์ ‘ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

dependencies {
    testImplementation 'io.rest-assured:rest-assured:3.3.0'
}

# ์†๋„

RestAssured๋Š” ๋ณ„๋„์˜ ๊ตฌ์„ฑ์—†์ด @WebMvcTest๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์™€ ๊ฐ™์ด @SpringBootTest๋กœ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค.

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Test {
    @LocalServerPort
    public int port;

    @BeforeEach
    void setUp() {
        RestAssured.port = port;
    }
    ...
}

@SpringBootTest๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋“ฑ๋ก๋œ Spring Bean์„ ์ „๋ถ€ ๋กœ๋“œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค. ๋ฐ˜๋ฉด์— @WebMvcTest๋Š” Presentation Layer์˜ Bean๋“ค๋งŒ ๋กœ๋“œํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋น ๋ฅด๋‹ค.

# ๊ฐ€๋…์„ฑ

@Test
public void getMember() {
    given().
            accept(MediaType.APPLICATION_JSON_VALUE).
    when().
            get("/members/1").
    then().
            log().all().
            statusCode(HttpStatus.OK).
            assertThat().body("id", equalTo(1)); 
}

RestAssured๋Š” BDD ์Šคํƒ€์ผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ  ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.


# 0904 - ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„ 5์›์น™ SOLID (SRP, OCP, LSP, ISP, DIP)

# SOLD๋ž€?

  • ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„๋Š” ๊ธด ์„ธ์›”๊ณผ ์ˆ˜๋งŽ์€ ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ๊ฑฐ์น˜๋ฉฐ 5๊ฐ€์ง€ ์›์น™์ด ์ •๋ฆฌ๋˜์—ˆ๋‹ค. ์ด๊ฒƒ์„ ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„์˜ 5์›์น™์ด๋ผ๊ณ  ํ•˜๋ฉฐ, ์•ž๊ธ€์ž๋ฅผ ๋”ฐ์„œ SOLID๋ผ๊ณ  ํ•œ๋‹ค.
    1. SPR(Single Responsibility Principle) : ๋‹จ์ผ ์ฑ…์ž„ ์›์น™
    2. OCP(Open Closed Principle) : ๊ฐœ๋ฐฉ ํ์‡„ ์›์น™
    3. LSP(Liskov Substitution Principle) : ๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›์น™
    4. ISP(Interface Segregation Principle) : ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™
    5. DIP(Dependency Inversion Principle) : ์˜์กด ์—ญ์ „ ์›์น™ ์ด ์›์น™๋“ค์€ ์‘์ง‘๋„๋Š” ๋†’์ด๊ณ  ๊ฒฐํ•ฉ๋„๋Š” ๋‚ฎ์ถ”์ž๋Š” ๊ณ ์ „ ์›์น™์„ ๊ฐ์ฒด ์ง€ํ–ฅ์˜ ๊ด€์ ์—์„œ ์žฌ์ •๋ฆฝํ•œ ๊ฒƒ์œผ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

# SRP = ๋‹จ์ผ ์ฑ…์ž„ ์›์น™

์–ด๋–ค ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ์˜ค์ง ํ•˜๋‚˜ ๋ฟ์ด์–ด์•ผ ํ•œ๋‹ค.

  • SRP๊ฐ€ ์•ˆ์ง€์ผœ์ง„ ์‚ฌ๋ก€
    • ๋ณ€์ˆ˜๋ ˆ๋ฒจ
      • ํ•˜๋‚˜์˜ ์†์„ฑ์ด ์—ฌ๋Ÿฌ ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š” ๊ฒฝ์šฐ
      • ์–ด๋–ค ๊ณณ์—์„œ๋Š” ์“ฐ๊ณ , ์–ด๋–ค ๊ณณ์—์„  ์•ˆ์“ฐ๋Š” ์†์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ
    • ๋ฉ”์†Œ๋“œ๋ ˆ๋ฒจ
      • ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ if๋ฌธ์ด ๋งŽ์„ ๊ฒฝ์šฐ

# OCP = ๊ฐœ๋ฐฉ ํ์‡„ ์›์น™

์†Œํ”„ํŠธ์›จ์–ด ์—”ํ‹ฐํ‹ฐ(ํด๋ž˜์Šค, ๋ชจ๋“ˆ, ํ•จ์ˆ˜ ๋“ฑ)๋Š” ํ™•์žฅ์— ๋Œ€ํ•ด์„œ๋Š” ์—ด๋ ค ์žˆ์–ด์•ผ ํ•˜์ง€๋งŒ ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ์ž์‹ ์˜ ํ™•์žฅ์—๋Š” ์—ด๋ ค์žˆ๊ณ , ์ฃผ๋ณ€์˜ ๋ณ€ํ™”์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์€ interface๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ํ•˜์—ฌ ํ•ด๊ฒฐํ•œ๋‹ค.
ํ˜„์‹ค์˜ ์˜ˆ๋ฅผ๋“ค๋ฉด ์ƒ์ ์ง์›์ด ์•„๋ฌด๋ฆฌ ๋ฐ”๋€๋‹ค๊ณ ํ•ด์„œ ์†๋‹˜์ด ์ƒํ’ˆ์„ ๊ตฌ๋งคํ•˜๋Š” ๋ฐ๋Š” ์ง€์žฅ์ด ์—†๋‹ค.

# LSP = ๋ฆฌ์Šค์ฝ”ํ”„ ์น˜ํ™˜ ์›์น™

์„œ๋ธŒํƒ€์ž…์€ ์–ธ์ œ๋‚˜ ์ž์‹ ์˜ ๊ธฐ๋ฐ˜ํƒ€์ž…์œผ๋กœ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ฆ‰, ํ•˜์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ์ƒ์œ„ํ˜• ๊ฐ์ฒด ์ฐธ์กฐ ๋ณ€์ˆ˜์— ๋Œ€์ž…ํ•ด ์ƒ์œ„ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ๋ฌธ์ œ๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์€ OOP 4๋Œ€ ํŠน์„ฑ์˜ ์ƒ์†, ์ธํ„ฐํŽ˜์ด์Šค ์›์น™์ด ์ž˜ ์ง€์ผœ์ง„๋‹ค๋ฉด LSP๋Š” ์ž๋™์œผ๋กœ ์ž˜ ์ ์šฉ๋œ ๊ฒƒ์ด๋‹ค. (์ฃผ๋กœ ์กฐ์ง๋„, ๊ณ„์ธต๋„ ๊ด€์ ์—์„œ์˜ ์ƒ์†์ด LSP๋ฅผ ์œ„๋ฐฐํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค)

# ISP = ์ธํ„ฐํŽ˜์ด์Šค ๋ถ„๋ฆฌ ์›์น™

ํด๋ผ์ด์–ธํŠธ๋Š” ์ž์‹ ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๋ฉ”์†Œ๋“œ์— ์˜์กด ๊ด€๊ณ„๋ฅผ ๋งบ์œผ๋ฉด ์•ˆ๋œ๋‹ค. ISP๋Š” SRP์™€ ๋น„์Šทํ•˜์ง€๋งŒ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•œ ๋‹ค๋ฅธ ํ•ด๊ฒฐ์ฑ…์„ ์ œ์•ˆํ•˜๊ณ  ์žˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด class ์‚ฌ๋žŒ implemnets ๊ตฐ์ธ ์ด๋ฉด ๊ตฐ์ธ ํ™๊ธธ๋™ = new ์‚ฌ๋žŒ() ์„ ํ†ตํ•ด ๊ตฐ์ธ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”์†Œ๋“œ๋งŒ์„ ์‚ฌ์šฉํ•˜๋„๋ก ์ œํ•œํ•˜๋Š” ๊ฒƒ์ด๋‹ค. SRP ์˜€๋‹ค๋ฉด class๋ฅผ ๋‚˜๋ˆ„๊ฒ ์ง€๋งŒ, ์ผ๋ฐ˜์ ์œผ๋ก  ISP๋ณด๋‹ค SRP๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค.

# DIP = ์˜์กด ์—ญ์ „ ์›์น™

๊ณ ์ฐจ์› ๋ชจ๋“ˆ์€ ์ €์ฐจ์› ๋ชจ๋“ˆ์— ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ์ถ”์ƒํ™”๋œ ๊ฒƒ์€ ๊ตฌ์ฒด์ ์ธ ๊ฒƒ์— ์˜์กดํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ๊ตฌ์ฒด์ ์ธ ๊ฒƒ์ด ์ถ”์ƒํ™”๋œ ๊ฒƒ์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค. ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ํด๋ž˜์Šค์— ์˜์กดํ•˜์ง€ ๋ง์ž.๋กœ ์š”์•ฝ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ์ž์‹ ๋ณด๋‹ค ๋ณ€ํ•˜๊ธฐ ์‰ฌ์šด ๊ฒƒ์— ์˜์กดํ•˜์ง€ ๋ง๋ผ๋Š” ๊ฒƒ์ด๋‹ค. ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์€ OCP์™€ ๋น„์Šทํ•œ๋ฐ, ๊ตฌ์ฒด์ ์ธ class๊ฐ€ ์•„๋‹Œ, ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•จ์œผ๋กœ์จ DIP๋ฅผ ํ•ด๊ฒฐํ•œ๋‹ค.

Last update: September 18, 2022 22:56
Contributors: ahnjs , jaesungahn91