DevLog ๐ถ
[๋ชจ๋์๋ฐ์ธ์ก์ ] ๋ฉ์๋ ์ฐธ์กฐ : ๋๋ค๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ์ฌ์ฉํ๊ธฐ ๋ณธ๋ฌธ
[๋ชจ๋์๋ฐ์ธ์ก์ ] ๋ฉ์๋ ์ฐธ์กฐ : ๋๋ค๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ์ฌ์ฉํ๊ธฐ
dolmeng2 2023. 4. 7. 00:14๐ฌ ๋ชจ๋ ์๋ฐ ์ธ ์ก์ ์ฑํฐ 3์ ์ฝ๊ณ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
โ๏ธ ๋ฉ์๋ ์ฐธ์กฐ
๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํด์ ๋ ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค์ด๋ณด์.
// Before
inventory.sort((a1, a2) ->
a1.getCourse().compareTo(a2.getCourse()));
// After
inventory.sort(comparing(Crew::getCourse));
๋ฉ์๋ ์ด๋ฆ์ ํ์ฉํ๋, '๋ฉ์๋ ์ฐธ์กฐ'๋ฅผ ํ์ฉํ๋ฉด ๋๋ค๋ฅผ ๋ ๊ฐ๊ฒฐํ๊ฒ ํํํ ์ ์๋ค.
๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ํ๊ธฐ ์ํด์๋ ๊ตฌ๋ถ์(::)๋ฅผ ํ์ฉํ๋ค.
๐ฑ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ
1. ์ ์ ๋ฉ์๋ ์ฐธ์กฐ
(args) -> ClassName.staticMethod(args) ==> ClassName::staticMethod
2. ๋ค์ํ ํ์์ ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ
(arg0, rest) -> arg0.instanceMethod(rest) ==> ClassName::instanceMethod
3. ๊ธฐ์กด ๊ฐ์ฒด์ ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ
(args) -> expr.instanceMethod(args) ==> expr::instanceMethod
์ฌ๊ธฐ์ ํต์ฌ์, ๋ฉ์๋ ์ฐธ์กฐ๊ฐ ์ฝํ ์คํธ์ ํ์๊ณผ ์ผ์นํด์ผ ํ๋ ๊ฒ์ด๋ค.
๋ฉ์๋ ์ฐธ์กฐ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋๋ค์์ ์ถ์ฝํ์ฌ ํธ์ถํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์, ๋๋ค์๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํจ์ํ ์ธํฐํ์ด์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค. ์ด๋, ํจ์ํ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋์ ๋ฉ์๋ ์ฐธ์กฐ ๋์ ๋ฉ์๋์ ์๊ทธ๋์ฒ๊ฐ ์ผ์นํด์ผ ํ๋ค.
๋ง์ ์ด๋ ๊ฒ ์ฐ๋๊น ์ด๋ ค์ด๋ฐ, ์ฝ๋๋ก ๋ณด๋ฉด ๊ฐ๋จํ๋ค.
public class Calculator {
public int sum(int a, int b) {
return a + b;
}
}
์ธ์๋ก ๋ฐ์ ๋ ๊ฐ์ ๋ํ๋ ๋ฉ์๋๊ฐ ์๋ค๊ณ ๊ฐ์ ํด๋ณด์. ์ฐ๋ฆฌ๋ ํธ์ถ๋ถ์์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
Calculator calculator = new Calculator();
IntBinaryOperator operator = calculator::sum;
์์ฑํ ๋ฉ์๋ ์ฐธ์กฐ์ธ calculator::sum์ ๋ฐํํ์ IntBinaryOperator๋ก ๋ฐ์๋ค.
IntBinaryOperator๋ int ํ์ ์ ๋งค๊ฐ๋ณ์ 2๊ฐ๋ฅผ ๋ฐ์ int ํ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ํจ์ํ ์ธํฐํ์ด์ค์ด๋ค.
์ด๋, calculator::sum์ ์๊ทธ๋์ฒ๋ (int, int) -> int์ด๊ณ , IntBinaryOperator ์ญ์ ๋์ผํ๋ค.
โ๏ธ ์์ฑ์ ์ฐธ์กฐ
์ ์ ๋ฉ์๋ ์ฐธ์กฐ์ฒ๋ผ, ํด๋์ค๋ช ::new๋ฅผ ํ์ฉํ๋ฉด ์์ฑ์์ ์ฐธ์กฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
// ๊ธฐ๋ณธ์ ์ธ ๊ฐ์ฒด ์์ฑ ๋ฐฉ๋ฒ
Crew crew = new Crew();
// ์์ฑ์ ์ฐธ์กฐ ์ด์ฉํ๊ธฐ
Supplier<Crew> sup = Crew::new;
Crew crew = sup.get(); // get์ ํตํด ๊ฐ์ฒด ๊ฐ์ ธ์ค๊ธฐ
// ๋งค๊ฐ๋ณ์๊ฐ ์กด์ฌํ ๊ฒฝ์ฐ ์์ฑ์ ์ฐธ์กฐ ์ด์ฉํ๊ธฐ
Function<String, Crew> func = Crew::new;
Crew crew = func.apply("journey"); // ์ธ์ ์ ๋ฌ์ด ๊ฐ๋ฅํ๋ค.
// ๋งค๊ฐ๋ณ์๊ฐ 2๊ฐ์ธ ๊ฒฝ์ฐ
BiFunction<String, Integer, Crew> bi = Crew::new;
Crew crew = bi.apply("journey", 23);
์ธ์๊ฐ ์ฌ๋ฌ ๊ฐ์ธ ๊ฒฝ์ฐ์๋, ์ฐ๋ฆฌ๊ฐ ์ง์ ์ปค์คํ ํ ์ธํฐํ์ด์ค๋ฅผ ํ์ฉํ๋ฉด ๋๋ค.
๋ง์ฝ ๋งค๊ฐ๋ณ์๊ฐ 4๊ฐ์ธ ๊ฒฝ์ฐ, ์์ฑ์ ์ฐธ์กฐ๋ฅผ ํ์ฉํ๊ณ ์ถ๋ค๋ฉด ์ ๋ค๋ฆญ์ ํ์ฉํ์ฌ ๋ค์๊ณผ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ์.
public interface CustomFunction<T1, T2, T3, T4, R> {
R apply(T1 t1, T2 t2, T3 t3, T4 t4);
}
// ๊ฐ๋จํ ํฌ๋ฃจ ํด๋์ค
public class Crew {
private final String name;
private final String nickname;
private final int age;
private final String courseName;
public Crew(final String name, final String nickname, final int age, final String courseName) {
this.name = name;
this.nickname = nickname;
this.age = age;
this.courseName = courseName;
}
}
๊ทธ๋ฌ๋ฉด ์ค์ ๋ก ์๋์ ๊ฐ์ด ์ ์ฉํด์ฃผ๋ฉด ๋๋ค.
CustomFunction<String, String, Integer, String, Crew> crewFactory = Crew::new;
๋ํ, ์์ฑ์ ์ฐธ์กฐ๋ฅผ ํ์ฉํ๋ฉด ์ธ์คํด์คํ ํ์ง ์๋๋ผ๋ ์์ฑ์์ ์ ๊ทผํ ์ ์๋ค.
public class Crew {
private final String courseName;
public Crew(final String courseName) {
this.courseName = courseName;
}
public String getCourseName() {
return courseName;
}
}
์์ ๊ฐ์ ๊ฐ๋จํ ํฌ๋ฃจ ํด๋์ค๊ฐ ์๋ค๊ณ ์๊ฐํด๋ณด์.
public class Main {
private static final Map<String, Function<String, Crew>> map = new HashMap<>();
public static void main(String[] args) throws IOException {
map.put("backend", Crew::new);
map.put("frontend", Crew::new);
Crew crew = getCrew("backend", "backend");
System.out.println(crew.getCourseName()); // backend
}
public static Crew getCrew(String course, String courseName) {
return map.get(course).apply(courseName);
}
}
์์ ์ฝ๋์ฒ๋ผ, map์ ํตํด ํน์ ํ ํด์๊ฐ์ key๋ก ๋๊ณ , ํด๋น ํด์๊ฐ์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋ฏธ๋ฆฌ ์์ฑํด๋๋ค. (์ผ์ข ์ ์บ์ฑ ๊ฐ๋ ์ด๋ค)
๊ทธ๋ฆฌ๊ณ , ํด๋น ํด์๊ฐ์ ํตํด map์ ์์ฒญํ๋ฉด .apply()๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ์ฌ์ ์ ์ธ์คํด์คํํ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ค ์ ์๋ค.
โ๏ธ ๋๋ค, ๋ฉ์๋ ์ฐธ์กฐ
์ฐ๋ฆฌ๋ ํฌ๋ฃจ์ ๋ํด ์ ๋ ฌํ๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์. ์ด๋, ๋๋ค๋ฅผ ํ์ฉํ์ฌ ๋ฉ์ง๊ฒ ๋ณํ์ ํด์ค ๊ฒ์ด๋ค.
1. sort() ๋ฉ์๋์๊ฒ ๋์ ํ๋ผ๋ฏธํฐํ ์ ์ฉํ๊ธฐ
// crew์ ๋ํ comparator ์์ฑํ๊ธฐ
public class CrewComparator implements Comparator<Crew> {
public int compare(Crew a1, Crew a2) {
return Integer.compare(a1.getAge(), a2.getAge());
}
}
// ๋ค์๊ณผ ๊ฐ์ด ์ธ์๋ก ์ ๋ฌํ ์ ์๋ค.
List<Crew> crews = new ArrayList<>();
crews.sort(new CrewComparator());
sort๊ฐ ์ด๋ค ์์ผ๋ก ์ ๋ ฌํ ๊ฒ์ธ์ง์ ๋ํ ๊ธฐ์ค์ ์ธ์๋ก ๋๊ฒจ์ค ์ ์๋ค.
2. ์๋ก์ด ํด๋์ค๋ฅผ ๋ง๋ค์ง ์๊ณ , ์ต๋ช ํด๋์ค ํ์ฉํ๊ธฐ
List<Crew> crews = new ArrayList<>();
crews.sort(new Comparator<Crew>() {
@Override
public int compare(final Crew o1, final Crew o2) {
return Integer.compare(o1.getAge(), o2.getAge());
}
});
ํด๋์ค๋ฅผ ์์ฑํ์ง ์๊ณ , ์ต๋ช ํด๋์ค๋ฅผ ํตํด์ ๋ฐ๋ก ์์ ๊ฐ์ด ์ ์๋ฅผ ํ์๋ค.
์ฐธ๊ณ ๋ก, age์ ํ์ ์ด Integer๋ผ๋ฉด ๋ฐ๋ก o1.getAge().compareTo(o2.getAge())๋ฅผ ํ์ฉํด๋ ์ข๋ค.
์์์๋ primitive ํ์ ์ ์ฌ์ฉํ๋ค๊ณ ๊ฐ์ ํ๊ณ Integer.compare๋ฅผ ํ์ฉํ์๋ค.
(int ํ์ ์ด๋ผ๊ณ ํด์ ๋ ๊ฐ์ ๋ฐ๋ก ๋บ ๊ฐ์ ์ฌ์ฉํ๋ฉด ์ค๋ฒํ๋ก๊ฐ ๋ฐ์ํ ์ ์๊ธฐ ๋๋ฌธ์ ์กฐ์ฌํด์ผ ํ๋ค.)
3. ๋๋ค ํํ์์ ์ฌ์ฉํด์ ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค๊ธฐ
ํ์ฌ Comparator๋ compare()๋ผ๋ ์ถ์ ๋ฉ์๋๊ฐ ํ๋๋ง ์กด์ฌํ๊ณ ์๊ธฐ ๋๋ฌธ์ ํจ์ํ ์ธํฐํ์ด์ค์ด๋ค.
์ด๋, ์ถ์ ๋ฉ์๋์ ์๊ทธ๋์ฒ (= ํจ์ ๋์คํฌ๋ฆฝํฐ)๋ (T, T) → int์ด๋ฉฐ, ์ฐ๋ฆฌ๋ ์ด๋ฌํ ์๊ทธ๋์ฒ์ ๋์ผํ๊ฒ ๋๋ค ํํ์์ ์์ฑํ ์ ์๋ค.
List<Crew> crews = new ArrayList<>();
crews.sort((Crew o1, Crew o2) -> Integer.compare(o1.getAge(), o2.getAge()));
์ปดํ์ผ๋ฌ๋ ์ปจํ ์คํธ๋ฅผ ํ์ฉํ์ฌ ๋๋ค์ ํ๋ผ๋ฏธํฐ ํ์์ ์ถ๋ก ํ ์ ์๋ค.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์์ ์ ์ธํ Crew๋ ์ ๊ฑฐํด์ค๋ ๋๋ค.
List<Crew> crews = new ArrayList<>();
crews.sort((o1, o2) -> Integer.compare(o1.getAge(), o2.getAge()));
์ ์ฝ๋๋ฅผ ๋ ๊ฐ๊ฒฐํ๊ฒ ํด๋ณด์.
Comparator๋ ๋ด๋ถ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
Function<? super T, ? extends U> keyExtractor) {
Objects.requireNonNull(keyExtractor);
return (Comparator<T> & Serializable)
(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}
Comparator๋ ์์ ๊ฐ์ด ๋ด๋ถ์ ์ผ๋ก comparing()์ด๋ผ๋ ์ ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ, ์ฌ๊ธฐ์ ๋ด๋ถ ์ธ์๋ก Function<T>ํ์ ๋ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค. Function์ ํจ์ ๋์คํฌ๋ฆฝํฐ๋ T → R์ด๊ณ , ์ฌ๊ธฐ์ T๋ ์ฐ๋ฆฌ๊ฐ ์ ๋ ฌํ ๊ฐ์ฒด, R๋ ์ ๋ ฌ ๊ธฐ์ค์ ๋ํ ํ๋๋ฅผ ์๋ฏธํ๋ค.
์ฐ๋ฆฌ๋ ํฌ๋ฃจ๋ฅผ ๋์ด ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ๋ค์๊ณผ ๊ฐ์ด Comparator์ ์ ์ ๋ฉ์๋ comparing์ ํธ์ถํ ์ ์๋ค.
Comparator<Crew> c = Comparator.comparing((Crew a) -> a.getAge());
๊ทธ๋ฆฌ๊ณ , ๋ค์ sort์ ์ธ์๋ก Comparator๋ฅผ ๋๊ฒจ์ฃผ์.
List<Crew> crews = new ArrayList<>();
crews.sort(Comparator.comparing((Crew crew) -> crew.getAge()));
4. ๋๋ค ํํ์์ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค๊ธฐ, ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ด์ฉํ์!
๋ค์๊ณผ ๊ฐ์ด ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ํตํด์ ์กฐ๊ธ ๋ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค ์ ์๋ค.
List<Crew> crews = new ArrayList<>();
crews.sort(Comparator.comparing(Crew::getAge));
์ด๋ ๊ฒ ๋๋ฉด ์ด๋ฐ์ ๋นํด ๋งค์ฐ ์ฝ๋๊ฐ ๊ฐ๊ฒฐํด์ง๋ฉฐ, crew์ age๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๋ผ๋ ๊ฒ์ ์ฝ๊ฒ ํ์ ํ ์ ์๊ฒ ๋๋ค.
โ๏ธ ๋๋ค ํํ์ ์์ฉํ๊ธฐ
์ฌ๋ฌ ๊ฐ์ ๋๋ค ํํ์์ ์กฐํฉํ์ฌ ๋ณต์กํ ๋๋ค ํํ์์ ๋ง๋ค ์ ์๋ค!
์ด๋ ๋ํดํธ ๋ฉ์๋ ๋๋ถ์ธ๋ฐ, ์ฑํฐ๊ฐ ๋์๊ฐ๋ฉฐ ์์ํ ํ๋ฆด ๋ด์ฉ์ด๊ธฐ ๋๋ฌธ์ ์ง๊ธ์ ๋์ด๊ฐ๋๋ก ํ์.
์กฐ๊ธ ๋ ์คํฌ์ ์ธ ๋ด์ฉ์ด๊ธฐ ๋๋ฌธ์ ๋ณ๋๋ก ํ์ด์ ์ค๋ช ํ๊ธฐ๋ณด๋ค๋, ์ด๋ฐ ๊ฒ๋ ์๊ตฌ๋… ํ๊ณ ๋์ด๊ฐ๋ ์ฉ๋๋ก ์ ๋ฆฌํ๋ฉด ์ข๋ค.
๐ฌ Comparator ํ์ฉํ๊ธฐ
์ฐ๋ฆฌ๊ฐ ๋ง์ฝ ํฌ๋ฃจ๋ค์ ๋์ด๋ฅผ ์ญ์์ผ๋ก ์ ๋ ฌํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
crews.sort(Comparator.comparing(Crew::getAge).reversed());
comparing()์ ๋ฆฌํด๊ฐ์ ๊ฒฐ๊ตญ Comparator์ด๊ธฐ ๋๋ฌธ์, chaining์ ํตํด์ ์ฝ๊ฒ ์ญ์ ๋ ฌ๋ ๊ฐ๋ฅํ๋ค.
Comparator์๋ reversed()๋ผ๋ ๋ํดํธ ๋ฉ์๋๊ฐ ๊ตฌํ๋์ด ์๊ธฐ ๋๋ฌธ์ ์ด๋ ๊ฒ ํธ์ถํ ์ ์๋ ๊ฒ์ด๋ค.
// Comparator.java
default Comparator<T> reversed() {
return Collections.reverseOrder(this);
}
์์ ์ฝ๋๊ฐ Comparator ์ธํฐํ์ด์ค์ ์ ์๋ ๋ํดํธ ๋ฉ์๋์ด๋ค.
ํน์, ํฌ๋ฃจ์ ๋์ด, ๊ทธ๋ฆฌ๊ณ ์ด๋ฆ์์ผ๋ก ์ ๋ ฌํ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํ ๊น?
crews.sort(Comparator.comparing(Crew::getAge)
.reversed()
.thenComparing(Crew::getName));
thenComparing์ ํตํด์ ๋ ๋ฒ์งธ ์ ๋ ฌ ๊ธฐ์ค์ ๋๊ฒจ์ฃผ๋ฉด ๋๋ค.
๐ฌ Predicate ํ์ฉํ๊ธฐ
๋ง์ฝ, ์ฐธ-๊ฑฐ์ง์ผ๋ก ๋ถ๋ฅ๋๋ ์กฐ๊ฑด์ ๋ํด ํํฐ๋ง์ ์งํํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฒด์ด๋์ ๊ฑธ์ด์ค ์ ์๋ค.
// ๋ฐฑ์๋์ธ ํฌ๋ฃจ๋ฅผ ํํฐ๋งํ๋ predicate
Predicate<Crew> coursePredicate = (Crew crew) -> crew.getCourseName().equals("backend");
// ํด๋น ํํฐ๋ง์ ๋ํด ๋ฐ์ ์ํค๋ predicate
Predicate<Crew> notBackendPredicate = coursePredicate.negate();
// predicate์ and (๊ต์งํฉ), or (ํฉ์งํฉ)
// 20์ด ์ด์์ด๋ฉด์ ๋ฐฑ์๋ ์ฝ์ค๊ฑฐ๋, ์ด๋ฆ์ด ์ ธ๋์ธ ์กฐ๊ฑด
coursePredicate.and(crew -> crew.getAge() >= 20)
.or(crew -> crew.getName().equals("journey"));
๐ฌ Function ํ์ฉํ๊ธฐ
h = f.andThen(g)
andThen์ ์ฃผ์ด์ง ํจ์๋ฅผ ๋จผ์ ์ ์ฉํ ๊ฒฐ๊ณผ๋ฅผ, ๋ค๋ฅธ ํจ์์ ์ ๋ ฅ์ผ๋ก ์ ๋ฌํ๋ค.
h = f.compose(g)
compose๋ ์ธ์๋ก ์ฃผ์ด์ง ํจ์๋ฅผ ๋จผ์ ์คํํ๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ถ ํจ์์ ์ธ์๋ก ์ ๊ณตํ๋ค.
// andThen() : g(f(x))
// (x + 1) * 2
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.andThen(g);
int result = h.apply(1); // (1+1) * 2 = 4
// compose() : f(g(x))
// (x * 2) + 1
Function<Integer, Integer> f = x -> x + 1;
Function<Integer, Integer> g = x -> x * 2;
Function<Integer, Integer> h = f.compose(g);
int result = h.apply(1); // (1*2) + 1 = 3
์ฝ๋ ๋ด๋ถ๋ ์ด๋ ๊ฒ ์๊ฒผ๋ค :D
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
๋ง์ง๋ง์ผ๋ก ์ ๋ฆฌํด๋ณด์! ์ฑํฐ 3์ ๋ด์ฉ์ด ๋ง์ง๋ง, ๊ทธ๋งํผ ์ค์ํ ๋ถ๋ถ์ด์๋ ๊ฒ ๊ฐ๋ค.
- ๋๋ค ํํ์์ ์ต๋ช ํจ์์ ์ผ์ข ์ด๋ค. ์ด๋ฆ์ ์์ง๋ง, ํ๋ผ๋ฏธํฐ ๋ฆฌ์คํธ, ๋ฐ๋, ๋ฐํ ํ์์ ๊ฐ์ง๋ฉฐ ์์ธ๋ฅผ ๋์ง ์ ์๋ค.
- ํจ์ํ ์ธํฐํ์ด์ค๋ ํ๋์ ์ถ์ ๋ฉ์๋๋ง์ ์ ์ํ๋ ์ธํฐํ์ด์ค์ด๋ค.
- ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ๊ธฐ๋ํ๋ ๊ณณ์์๋ง ๋๋ค ํํ์์ ์ฌ์ฉํ ์ ์๋ค.
- ๋๋ค ํํ์์ ์ด์ฉํด์ ํจ์ํ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋๋ฅผ ์ฆ์์ผ๋ก ์ ๊ณตํ ์ ์์ผ๋ฉฐ, ๋๋ค ํํ์ ์ ์ฒด๊ฐ ํจ์ํ ์ธํฐํ์ด์ค์ ์ธ์คํด์ค๋ก ์ทจ๊ธ๋๋ค.
- ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ํ์ฉํ๋ฉด ๋ฉ์๋ ๊ตฌํ์ ์ฌ์ฌ์ฉํ๊ณ , ์ง์ ์ ๋ฌํ ์ ์๋ค.