์์คํ (System)
๋ณต์ก์ฑ์ ์ฃฝ์์ด๋ค. ๊ฐ๋ฐ์์๊ฒ์ ์๊ธฐ๋ฅผ ์์๊ฐ๋ฉฐ, ์ ํ์ ๊ณํํ๊ณ ์ ์ํ๊ณ ํ ์คํธํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ ๋ค.
์์คํ ์ ์๊ณผ ์์คํ ์ฌ์ฉ์ ๋ถ๋ฆฌํ๋ผ.
- ์ํํธ์จ์ด ์์คํ
์
์ค๋น ๊ณผ์
๊ณผ๋ฐํ์ ๋ก์ง
์ ๋ถ๋ฆฌํด์ผ ํ๋ค. - ์์ ๋จ๊ณ๋ ๋ชจ๋ ์ดํ๋ฆฌ์ผ์ด์
์ด ํ์ด์ผ ํ
๊ด์ฌ์ฌ
์ด๋ค. ๊ด์ฌ์ฌ ๋ถ๋ฆฌ
๋ ์ฐ๋ฆฌ ๋ถ์ผ์์ ๊ฐ์ฅ ์ค๋๋๊ณ ๊ฐ์ฅ ์ค์ํ ์ค๊ณ ๊ธฐ๋ฒ ์ค ํ๋๋ค.
public Service getService() {
if (service == null)
service = new MyServiceImpl(...); // ๋ชจ๋ ์ํฉ์ ์ ํฉํ ๊ธฐ๋ณธ๊ฐ์ผ๊น?
return service;
}
์ด๊ธฐํ ์ง์ฐ(Lazy Initialization) ํน์ ๊ณ์ฐ ์ง์ฐ(Lazy Evalution)์ด๋ผ๋ ๊ธฐ๋ฒ์ด๋ค.
์ค์ ๋ก ํ์ํ ๋๊น์ง ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ ๋ถํ๊ฐ ์์ด์ง๋ค. ๋ฐ๋ผ์ ์ดํ๋ฆฌ์ผ์ด์
์ ์์ํ๋๋ฐ ์์ฃผ ๋น ๋ฅด๋ค.
์ด๋ค ๊ฒฝ์ฐ์๋ null
์ ๋ฐํํ์ง ์๋๋ค.
ํ์ง๋ง ์๋น์ค๋ MyServiceImpl
ํด๋์ค์ ์์กดํ๊ฒ ๋๋ค. MyServiceImpl
์ ์ฌ์ฉํ์ง ์๋๋ผ๋ ์์กด์ฑ์ ํด๊ฒฐํ์ง ์์ผ๋ฉด ์ปดํ์ผ์ด ์๋๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ํ
์คํธ ์ํ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
๋ง์ฝ MyServiceImpl
๊ฐ์ฒด๊ฐ ๋ฌด๊ฑฐ์ด ๊ฐ์ฒด๋ผ๋ฉด ํ
์คํธ๋ฅผ ์ํ Mock Object๋ฅผ serviceํ๋์ ๋์
ํด์ผ ํ๋ฉฐ, ์ด๋ ๊ธฐ์กด์ runtime ๋ก์ง์ ๊ด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๊ฐ๋ฅํ ๊ฒฝ์ฐ์ ์
๋ฅผ ๊ณ ๋ คํด์ผ ํ๋ ๋ฌธ์ ๋ ๋ฐ์ํ๋ค.
์ด๋ฌํ ์์ฑ/์ฌ์ฉ์ ๋ถ์ฐ์ ๋ชจ๋์ฑ์ ์ ํดํ๊ณ ์ฝ๋์ ์ค๋ณต์ ๊ฐ์ ธ์ค๋ฏ๋ก ์ ์ ๋๋ ๊ฒฌ๊ณ ํ ์์คํ ์ ๋ง๋ค๊ธฐ ์ํด์๋ ์ ์ญ์ ์ด๊ณ ์ผ๊ด๋ ์์กด์ฑ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ํตํด ์์ ๊ฐ์ ์์ ํธ์ ์ฝ๋๋ค์ด ๋ชจ๋์ฑ์ ์ ํด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ๋ง์์ผ ํ๋ค.
Main ๋ถ๋ฆฌ
์๋์ ๊ทธ๋ฆผ์ฒ๋ผ ์์ฑ๊ณผ ๊ด๋ จ๋ ์ฝ๋๋ ๋ชจ๋ main์ด๋ main์ด ํธ์ถํ๋ ๋ชจ๋๋ก ์ฎ๊ธฐ๊ณ ๋๋จธ์ง ์์คํ
์ ๋ชจ๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋์๊ณ ๋ชจ๋ ์์กด์ฑ์ด ์ฐ๊ฒฐ๋์๋ค๊ณ ๊ฐ์ ํ๊ณ ๋น์ฆ๋์ค ๋ก์ง์ ์ง์คํ ์ ์๋ค.
ํฉํ ๋ฆฌ(Factory)
์ด๋ค ๊ฒฝ์ฐ์๋ ์์ฑ์ ๊ด๋ จ๋ ๋ถ๋ถ์ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ฒฐ์ ํ ํ์๊ฐ ์๋ค. ๊ทธ๋ฐ ๋ถ๋ถ์ Factory Pattern์ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๊ฒฐ์ ํ์ง๋ง ์ง์ ์์ฑํ๋ ๋ถ๋ถ์ ์ฐ๊ด์ฑ์ ์ ๊ฑฐํ๋ค.
์์กด์ฑ ์ฃผ์ (Dependency Injection)
์ ์ด ์ญ์ (Inversion of Control IOC)์ ์ ์ฉํ ๋ฉ์ปค๋์ฆ์ด๋ค. ์ธ์คํด์ค๋ฅผ ์์ฑํ ์ฑ
์์ ์ง๋ main
์ด๋ ํน์ ์ปจํ
์ด๋
๋ฅผ ์ฌ์ฉํ๋ค.
์์กด์ฑ์ ์ฃผ์
ํ๊ธฐ ์ํด์๋ ๋ณดํต setter
๋ฉ์๋๋ ์์ฑ์๋ฅผ ์ ๊ณตํด์ผ ํ๋ค.
๊ฐ์ฅ ๋๋ฆฌ ์๋ ค์ง ์คํ๋ง ํ๋ ์์ํฌ๋ ์๋ฐ DI ์ปจํ ์ด๋๋ฅผ ์ ๊ณตํ๋ค. ๊ฐ์ฒด ์ฌ์ด ์์กด์ฑ์ XML์ ํตํด ์ ์ ๋๋ค.
ํ์ฅ
๋ด์ผ์ ์๋ก์ด ์คํ ๋ฆฌ์ ๋ง์ถฐ ์์คํ ์ ์กฐ์ ํ๊ณ ํ์ฅํ๋ฉด ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ณต์ ์ด๊ณ ์ ์ง์ ์ธ ์ ์์ผ ๋ฐฉ์์ ํต์ฌ์ด๋ค. ๊นจ๋ํ ์ฝ๋๋ ์ฝ๋ ์์ค์์ ์์คํ ์ ์กฐ์ ํ๊ณ ํ์ฅํ๊ธฐ ์ฝ๊ฒ ๋ง๋ ๋ค.
์๋์ ์ฝ๋๋ EJB2๋ฅผ ์์๋ฐ์ ๊ตฌํํ Bussiness Logic์ด๋ค.
/* Code 2-1(Listing 11-1): An EJB2 local interface for a Bank EJB */
package com.example.banking;
import java.util.Collections;
import javax.ejb.*;
public interface BankLocal extends java.ejb.EJBLocalObject {
String getStreetAddr1() throws EJBException;
String getStreetAddr2() throws EJBException;
String getCity() throws EJBException;
String getState() throws EJBException;
String getZipCode() throws EJBException;
void setStreetAddr1(String street1) throws EJBException;
void setStreetAddr2(String street2) throws EJBException;
void setCity(String city) throws EJBException;
void setState(String state) throws EJBException;
void setZipCode(String zip) throws EJBException;
Collection getAccounts() throws EJBException;
void setAccounts(Collection accounts) throws EJBException;
void addAccount(AccountDTO accountDTO) throws EJBException; }
/* Code 2-2(Listing 11-2): The corresponding EJB2 Entity Bean Implementation */
package com.example.banking;
import java.util.Collections;
import javax.ejb.*;
public abstract class Bank implements javax.ejb.EntityBean {
// Business logic...
public abstract String getStreetAddr1();
public abstract String getStreetAddr2();
public abstract String getCity();
public abstract String getState();
public abstract String getZipCode();
public abstract void setStreetAddr1(String street1);
public abstract void setStreetAddr2(String street2);
public abstract void setCity(String city);
public abstract void setState(String state);
public abstract void setZipCode(String zip);
ublic abstract Collection getAccounts();
public abstract void setAccounts(Collection accounts);
public void addAccount(AccountDTO accountDTO) {
InitialContext context = new InitialContext();
AccountHomeLocal accountHome = context.lookup("AccountHomeLocal");
AccountLocal account = accountHome.create(accountDTO);
Collection accounts = getAccounts(); accounts.add(account);
}
// EJB container logic public
abstract void setId(Integer id);
public abstract Integer getId();
public Integer ejbCreate(Integer id) { ... }
public void ejbPostCreate(Integer id) { ... }
// The rest had to be implemented but were usually empty:
public void setEntityContext(EntityContext ctx) {}
public void unsetEntityContext() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void ejbLoad() {}
public void ejbStore() {}
public void ejbRemove() {}
}
์์ ์ฝ๋๋ EJB2
์ ์ปจํ
์ด๋์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋๋ค. ํ์์๋ ๋ฉ์๋๋ฅผ ์์๋ฐ์์ผ ํ๋ฉฐ ๋ฉ๊ทธ๋ฌ๋ ๋จ์์๋ค.
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ๋ ๊ฐ๋
์กฐ์ฐจ ๋ฟ๋ฆฌ๊ฐ ํ๋ค๋ฆฐ๋ค.
ํก๋จ(cross-cutting) ๊ด์ฌ์ฌ
EJB2
๋ ๊ด์ฌ์ฌ๋ฅผ ๊ฑฐ์ ์๋ฒฝํ๊ฒ ๋ถ๋ฆฌํด ๋๋ค. ์๋ฅผ ๋ค์ด ํธ๋์ญ์
, ๋ณด์, ์ผ๋ถ ์์์ ์ธ ๋์๊น์ง ๋ถ๋ฆฌํด๋๋ค.
์ด๋ฐ ๊ด์ ์งํฅ ํ๋ก๊ทธ๋๋ฐ(Aspect-Oriented Programming AOP)์ ์๊ฒฌํ๋ค๊ณ ๋ณด์ธ๋ค.
์๋ฐ ํ๋ก์
- ์๋ฐ ํ๋ก์๋ ๋จ์ํ ์ํฉ์ ์ ํฉํ๋ค. ๊ฐ๋ณ ๊ฐ์ฒด๋ ํด๋์ค์์ ๋ฉ์๋ ํธ์ถ์ ๊ฐ์ธ๋ ๊ฒฝ์ฐ๋ ์ข์ ์๋ค.
- ํ๋ก์ API์๋ InvocationHandler๋ฅผ ๋๊ฒจ ์ค์ผ ํ๋ค.
- ์ฝ๋๋ ์๋นํ ๋ง์ผ๋ฉฐ ์ ๋ฒ ๋ณต์กํ๋ค. โ ๊นจ๋ํ ์ฝ๋๋ฅผ ์์ฑํ๊ธฐ ์ด๋ ต๋ค.
์์ ์๋ฐ AOP ํ๋ ์ ์ํฌ
์์ ๊ทธ๋ฆผ์ ์ฝ๋๋ก ํํํ๋ฉด ์๋์ ๊ฐ๋ค.
/* Code 3-3: Code 3-2์ ํ์ฉ๋ฒ */
XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("app.xml", getClass()));
Bank bank = (Bank) bf.getBean("bank");
๊ตฌ์กฐ ์ ์๋ฅผ ์ํ xml์ ๋ค์ ์ฅํฉํ๊ณ ์ฝ๊ธฐ ํ๋ค ์๋ ์์ง๋ง Java Proxy๋ณด๋ค๋ ํจ์ฌ ๊ฐ๊ฒฐํ๋ค.
์ด ๊ฐ๋
์ ์๋์ ์ค๋ช
ํ EJB3
์ ๊ตฌ์กฐ ๊ฐํธ์ ํฐ ์ํฅ์ ๋ฏธ์ณค๋ค. EJB3
์ xml์ Java annotation์ ์ฌ์ฉํด cross-cutting concerns๋ฅผ ์ ์ํ๊ณ ์ํฌํธํ๊ฒ ๋์๋ค.
์๋์ ๊ฐ์ด EJB2
๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ณด๋ค ํจ์ฌ ๊ฐ๊ฒฐํ๊ณ ๊ฒฐํฉ๋๊ฐ ๋ฎ์์ง ๊ฒ์ ํ์ธ ํ ์ ์๋ค.
/* Code 3-4(Listing 11-5): An EBJ3 Bank EJB */
package com.example.banking.model;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.Collection;
@Entity
@Table(name = "BANKS")
public class Bank implements java.io.Serializable {
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Embeddable // An object โinlinedโ in Bankโs DB row
public class Address {
protected String streetAddr1;
protected String streetAddr2;
protected String city;
protected String state;
protected String zipCode;
}
@Embedded
private Address address;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="bank")
private Collection<Account> accounts = new ArrayList<Account>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void addAccount(Account account) {
account.setBank(this);
accounts.add(account);
}
public Collection<Account> getAccounts() {
return accounts;
}
public void setAccounts(Collection<Account> accounts) {
this.accounts = accounts;
}
}
- ์์์ฑ ์ ๋ณด๋ ํ์ํ๋ค๋ฉด XML๋ฐฐ์น ๊ธฐ์ ์๋ก ์ฎ๊ฒจ๋ ๊ด์ฐฎ๋ค. ๊ทธ๋ฌ๋ฉด ์์ํ POJO๋ง ๋จ๋๋ค.
AspectJ ๊ด์
- AspectJ๋ AOP๋ฅผ ์คํํ๊ธฐ ์ํ full-featured tool์ด๋ผ ์ผ์ปฌ์ด์ง๋ค.
- 8~90%์ ๊ฒฝ์ฐ์๋ Spring AOP์ JBoss AOP๋ก๋ ์ถฉ๋ถํ์ง๋ง AspectJ๋ ํจ์ฌ ๊ฐ๋ ฅํ ์์ค์ AOP๋ฅผ ์ง์ํ๋ค.
- ๋ค๋ง ์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์๋ก์ด ํด, ์ธ์ด ๊ตฌ์กฐ, ๊ด์ต์ ์ธ ์ฝ๋๋ฅผ ์ตํ์ผ ํ๋ค๋ ๋จ์ ๋ ์กด์ฌํ๋ค.
- ์ต๊ทผ ์๊ฐ๋ โannotation-form AspectJโ๋ก ์ธํด ์ ์ฉ์ ํ์ํ ๋ ธ๋ ฅ์ ๋ง์ด ์ค์ด๋ค์๋ค๊ณ ํ๋ค.
- AOP์ ๋ํ ๋ ์์ธํ ๋ด์ฉ์ [AspectJ], [Colyer], [Spring]๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋ฐ๋๋ค.
ํ ์คํธ ์ฃผ๋ ์์คํ ์ํคํ ์ฒ ๊ตฌ์ถ
- ์ฝ๋ ๋ ๋ฒจ์์๋ถํฐ ์ํคํ ์ณ์ ๋ถ๋ฆฌ๋(decouple๋) ํ๋ก๊ทธ๋จ ์์ฑ์ ๋น์ ์ ์ํคํ ์ณ๋ฅผ test driveํ๊ธฐ ์ฝ๊ฒ ๋ง๋ค์ด ์ค๋ค.
- ์ฒ์์๋ ์๊ณ ๊ฐ๋จํ ๊ตฌ์กฐ์์ ์์ํ์ง๋ง ํ์์ ๋ฐ๋ผ ์๋ก์ด ๊ธฐ์ ์ ์ถ๊ฐํด ์ ๊ตํ ์ํคํ ์ณ๋ก ์งํํ ์ ์๋ค.
- ๋ํ decouple๋ ์ฝ๋๋ user story, ๊ท๋ชจ ๋ณํ์ ๊ฐ์ ๋ณ๊ฒฝ์ฌํญ์ ๋ ๋น ๋ฅด๊ฒ ๋์ฒํ ์ ์๋๋ก ์ฐ๋ฆฌ๋ฅผ ๋์ ์ค๋ค.
- ๋๋ฆฌ์ด BDUF(Big Design Up First)์ ๊ฐ์ ๋ฐฉ์์ ๋ณ๊ฒฝ์ด ์๊ธธ ๊ฒฝ์ฐ ๊ธฐ์กด์ ๊ตฌ์กฐ๋ฅผ ๋ฒ๋ ค์ผ ํ๋ค๋ ์ฌ๋ฆฌ์ ์ ํญ, ์ํคํ ์ณ์ ๋ฐ๋ฅธ ๋์์ธ์ ๋ํ ๊ณ ๋ฏผ ๋ฑ ๋ณํ์ ์ ์ฐํ์ง ๋ชปํ ๋จ์ ๋ค์ ๊ฐ์ ธ์ค๊ฒ ๋๋ค.
์ด์์ ์ธ ์์คํ ์ํคํ ์ณ๋ ๊ฐ๊ฐ POJO๋ก ๋ง๋ค์ด์ง ๋ชจ๋ํ๋ ๊ด์ฌ ๋ถ์ผ ์์ญ(modularized domains of concern)์ผ๋ก ์ด๋ฃจ์ด์ ธ์ผ ํ๋ค. ๋ค๋ฅธ ์์ญ๋ผ๋ฆฌ๋ Aspect์ ๊ฐ๋ ์ ์ฌ์ฉํด ์ต์ํ์ ๊ฐ์ญ์ผ๋ก ํตํฉ๋์ด์ผ ํ๋ค. ์ด๋ฌํ ์ํคํ ์ณ๋ ์ฝ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก test-driven๋ ์ ์๋ค.
์์ฌ ๊ฒฐ์ ์ ์ต์ ํํ๋ผ
์ถฉ๋ถํ ํฐ ์์คํ ์์๋(๊ทธ๊ฒ์ด ๋์์ด๊ฑด ์ํํธ์จ์ด์ด๊ฑด) ํ ์ฌ๋์ด ๋ชจ๋ ๊ฒฐ์ ์ ๋ด๋ฆด ์๋ ์๋ค. ๊ฒฐ์ ์ ์ต๋ํ ๋ง์ ์ ๋ณด๊ฐ ๋ชจ์ผ ๋๊น์ง ๋ฏธ๋ฃจ๊ณ ์๊ธฐ๊ฐ ๋์์ ๊ฒฝ์ฐ ํด๋น ํํธ์ ์ฑ ์์(์ฌ๊ธฐ์๋ ์ฌ๋์ด ์๋ ๋ชจ๋ํ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ปํ๋ค)์๊ฒ ๋งก๊ธฐ๋ ๊ฒ์ด ๋ถํ์ํ ๊ณ ๊ฐ ํผ๋๋ฐฑ๊ณผ ๊ณ ํต์ ๋์ด์ค ๊ฒ์ด๋ค.
๋ชจ๋ํ๋ ๊ด์ฌ ๋ถ์ผ๋ก ์ด๋ฃจ์ด์ง POJO ์์คํ ์ (๋ณํ์ ๋ํ)๋ฏผ์ฒฉํจ์ ๊ฐ์ฅ ์ต์ ์ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์ ์์ ์ต์ ์ ์ ํ์ ํ ์ ์๊ฒ ๋์์ค๋ค. ๊ฒฐ์ ์ ํ์ํ ๋ณต์ก๋ ๋ํ ๊ฒฝ๊ฐ๋๋ค.
๋ช ๋ฐฑํ ๊ฐ์น๊ฐ ์์ ๋ ํ์ค์ ํ๋ช ํ๊ฒ ์ฌ์ฉํ๋ผ
๋ง์ ์ํํธ์จ์ด ํ๋ค์ ํจ์ฌ ๊ฐ๋ณ๊ณ ์ง๊ด์ ์ธ ๋์์ธ์ด ๊ฐ๋ฅํ์์๋ ๋ถ๊ตฌํ๊ณ ๊ทธ์ ํ์ค์ด๋ผ๋ ์ด์ ๋ง์ผ๋ก EJB2 ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ค. ํ์ค์ ์ฌ์ทจํด โ๊ณ ๊ฐ์ ์ํ ๊ฐ์น ์ฐฝ์ถโ์ด๋ผ๋ ๋ชฉํ๋ฅผ ์์ด ๋ฒ๋ ธ๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ค์ ์ฌ์ฉํ๋ฉด ์์ด๋์ด์ ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ , ์ ์ ํ ๊ฒฝํ์ ๊ฐ์ง ์ฌ๋์ ๊ตฌํ๊ธฐ ์ฌ์ฐ๋ฉฐ ์ข์ ์์ด๋์ด๋ฅผ ์บก์ํํ๊ธฐ ์ฝ๊ณ , ์ปดํฌ๋ํธ๋ฅผ ์ฎ๊ธฐ ์ฝ๋ค.
์์คํ ์ ๋๋ฉ์ธ ํนํ ์ธ์ด๊ฐ ํ์ํ๋ค
์ข์ DSL์ ๋๋ฉ์ธ ์์ญ์ ๊ฐ๋
๊ณผ ์ค์ ๊ตฌํ๋ ์ฝ๋ ์ฌ์ด์ ์ํต์ ๊ฐ๊ทน
์ ์ค์ฌ ๋๋ฉ์ธ ์์ญ์ ์ฝ๋ ๊ตฌํ์ผ๋ก ๋ฒ์ญํ๋ ๋ฐ์ ์ค์ญ์ ์ค์ฌ์ค๋ค. DSL์ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ๋ฉด ์ฝ๋ ๋ฉ์ด๋ฆฌ์ ๋์์ธ ํจํด์ ์ถ์๋๋ฅผ ๋์ฌ ์ฃผ๋ฉฐ ๊ทธ์ ๋ฐ๋ผ ์ฝ๋์ ์๋๋ฅผ ์ ์ ํ ์ถ์ํ ๋ ๋ฒจ์์ ํํํ ์ ์๊ฒ ํด์ค๋ค.
DSL์ โ๋ชจ๋ ๋จ๊ณ์์์ ์ถ์ํโ์ โ๋ชจ๋ ๋๋ฉ์ธ์ POJOํโ๋ฅผ ๊ณ ์ฐจ์์ ๊ท์น๊ณผ ์ ์ฐจ์์ ๋ํ ์ผ ์ ๋ฐ์ ๊ฑธ์ณ ๋์ ์ค๋ค.
๊ฒฐ๋ก
์์คํ ์ ๊นจ๋ํด์ผ ํ๋ฉฐ ๋ชจ๋ ์ถ์ํ ๋จ๊ณ์์ ์๋๋ ๋ช ํํ ํํํด์ผ ํ๋ค.