๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd๐ŸŒฑ/Java

๋””๋ฏธํ„ฐ ๋ฒ•์น™ (Law of Demeter)์ด๋ž€?

by dkswnkk 2023. 2. 1.

์ตœ๊ทผ ํด๋ฆฐ์ฝ”๋“œ๋ฅผ ์ฝ๋˜ ์ค‘ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์šฉ์–ด ์ž์ฒด๋Š” ์ƒ์†Œํ•˜๊ธด ํ•œ๋ฐ ๋ฒ•์น™์˜ ๋‚ด์šฉ ์ž์ฒด๋Š” ํฌ๊ฒŒ ์–ด๋ ต์ง€ ์•Š๊ณ , ํ‰์ƒ์‹œ ๊ฐœ๋ฐœ์—์„œ ํ”ํžˆ ๋งˆ์ฃผ์น  ์ˆ˜ ์žˆ๋Š” ๋‚ด์šฉ์„ ๋‹ค๋ฃฌ ๋ฒ•์น™์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

๋””๋ฏธํ„ฐ ๋ฒ•์น™์ด๋ž€?

๋””๋ฏธํ„ฐ ๋ฒ•์น™(Law of Demeter)์€ ๋ฐ๋ฉ”ํ…Œ๋ฅด ๋ฒ•์น™์ด๋ผ๊ณ ๋„ ๋ถˆ๋ฆฌ๋ฉฐ ์ค„์—ฌ์„œ LoD๋ผ๊ณ ๋„ ๋ถˆ๋ฆฝ๋‹ˆ๋‹ค. ์ด ๋ฒ•์น™์€ "์ตœ์†Œํ•œ์˜ ์ง€์‹ ์›์น™(The Principle of Least Knowledge)์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ์œผ๋ฉฐ, ๋ชจ๋“ˆ์€ ์ž์‹ ์ด ์กฐ์ž‘ํ•˜๋Š” ๊ฐ์ฒด์˜ ์†์‚ฌ์ •์„ ๋ชฐ๋ผ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ Demeter๋ผ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋˜ ๊ฐœ๋ฐœ์ž๋“ค์€ ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ง€๋‚˜์น˜๊ฒŒ ๋งŽ์€ ์ •๋ณด๋ฅผ ์•Œ๊ณ  ์žˆ๋‹ค ๋ณด๋‹ˆ, ์„œ๋กœ์— ๋Œ€ํ•œ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋†’์•„์ง€๊ณ  ์ด๋กœ ์ธํ•ด ์ข‹์ง€ ๋ชปํ•œ ์„ค๊ณ„๋ฅผ ์•ผ๊ธฐํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋ฐœ๊ฒฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ณ ์ž ๋‹ค๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์–ด๋– ํ•œ ์ž๋ฃŒ(๋‚ด๋ถ€ ๊ตฌ์กฐ)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ์ˆจ๊ธฐ๊ณ  ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๊ณต๊ฐœํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋Š”๋ฐ ์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์ž…๋‹ˆ๋‹ค.

์ฆ‰, ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งํ•˜๋ฉด ์—ฌ๋Ÿฌ๊ฐœ์˜ .(dot)์„ ์ตœ๋Œ€ํ•œ ์‚ฌ์šฉํ•˜์ง€ ๋ง๋ผ๋Š” ๋ฒ•์น™์œผ๋กœ ๋งํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์ค€์ˆ˜ํ•˜๊ฒŒ ๋˜๋ฉด ์บก์Šํ™”๋ฅผ ๋†’์—ฌ ๊ฐ์ฒด์˜ ์ž์œจ์„ฑ๊ณผ ์‘์ง‘๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ๋ฒˆ ์ง์ ‘์ ์ธ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์ข€ ๋” ์ž์„ธํžˆ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋””๋ฏธํ„ฐ ๋ฒ•์น™ ์˜ˆ์ œ

@Getter
public class Employee {

    private final String name;
    private final Enterprise enterprise;
    
    public int getEnterprisePostalCode() {
        return this.enterprise.getAddressPostalCode();
    }

}

@Getter
public class Enterprise {

    private final int employeeNumber;
    private final String domain;
    private final Address address;

    public int getAddressPostalCode() {
        return this.address.getPostalCode();
    }
    
}

@Getter
public class Address {

    private final String street;
    private final int postalCode;
    private final String city;

}

์œ„์™€ ๊ฐ™์ด Employee, Enterprise, Address ํด๋ž˜์Šค๊ฐ€ ์ •์˜๋˜์–ด ์žˆ๊ณ , ์ง์›์ด ์†ํ•œ ํšŒ์‚ฌ์˜ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

public class App {

    public static void main(String[] args) {
        final Address address = new Address("์ข…๋กœ๊ตฌ ์ฒญ์™€๋Œ€๋กœ 1", 03054, "์„œ์šธํŠน๋ณ„์‹œ");
        final Enterprise enterprise = new Enterprise(100, "์ฒญ์™€๋Œ€", address);
        final Employee employee = new Employee("์•ˆ์ฃผํ˜•", enterprise);

        // 1๋ฒˆ - ๋””๋ฏธํ„ฐ ๋ฒ•์น™ ์œ„๋ฐ˜ ์ฝ”๋“œ!!
        System.out.println(employee.getEnterprise().getAddress().getPostalCode());

        // 2๋ฒˆ - ๋””๋ฏธํ„ฐ ๋ฒ•์น™ ์ค€์ˆ˜ ์ฝ”๋“œ!!
        System.out.println(employee.getEnterprisePostalCode()); 
    }
}

์œ„์˜ ๋‘ ๋กœ์ง์€ ์ •๋ง ํ”ํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ์ด์ง€๋งŒ ํ•˜๋‚˜๋Š” ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์œ„๋ฐ˜ํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ํšŒ์‚ฌ์˜ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์–ป๋Š” ๋กœ์ง์ด์ง€๋งŒ 1๋ฒˆ์˜ ๊ฒฝ์šฐ๋Š” 2๋ฒˆ๊ณผ ๋‹ฌ๋ฆฌ ๊ฐ์ฒด์—๊ฒŒ ์šฐํŽธ๋ฒˆํ˜ธ๋ฅผ ์–ป์–ด์˜ค๊ธฐ ์œ„ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ž๋ฃŒ๋ฅผ ์ง์ ‘ ํ™•์ธํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ฒ˜์Œ์— ๋งํ–ˆ๋˜ ๋ฌธ์ œ์ธ ๋‹ค๋ฅธ ๊ฐ์ฒด๊ฐ€ ์–ด๋– ํ•œ ์ž๋ฃŒ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋Š”์ง€ ์ง€๋‚˜์น˜๊ฒŒ ์ž˜ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

2๋ฒˆ์˜ ๊ฒฝ์šฐ๋Š” 1๋ฒˆ์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ๊ฐœ์˜ .(dot)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ณ , ํ•จ์ˆ˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ†ตํ•ด ์ž๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์ž˜ ์ค€์ˆ˜ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ ํ”Œ๋กœ์šฐ

์ฆ‰, A์—์„œ C์˜ ์ •๋ณด๋ฅผ ์–ป์–ด ์˜ค๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์€ C์—์„œ B๋กœ, B์—์„œ A๋กœ ๊ฐ’์„ ์บก์Šํ™”ํ•˜์—ฌ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

 

์˜ˆ์™ธ

๋‹จ, DTO์™€ ์ž๋ฃŒ๊ตฌ์กฐ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ๋‹น์—ฐํ•˜๋ฏ€๋กœ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ Java Stream API์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹(method chaining)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์œ„๋ฐ˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋””๋ฏธํ„ฐ ๋ฒ•์น™์€ ๊ฒฐํ•ฉ๋„์™€ ๊ด€๋ จ๋œ ์ด์•ผ๊ธฐ์ด๋ฏ€๋กœ, ๋ณธ์งˆ์„ ์žŠ๊ณ  .(dot)์— ๋งค๋ชฐ๋˜์–ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

 

์ •๋ฆฌ

์ •๋ฆฌํ•˜์ž๋ฉด ๋””๋ฏธํ„ฐ์˜ ๋ฒ•์น™์€ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋ฅผ ์™ธ๋ถ€๋กœ ๋“œ๋Ÿฌ๋‚ด์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋ฉฐ ์ด๋ฅผ ์ค€์ˆ˜ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ์ฒด ๊ฐ„ .(dot)๋ฅผ ์ตœ๋Œ€ํ•œ ์“ฐ์ง€ ์•Š๋„๋ก ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ตœ์ข…์ ์œผ๋กœ ๋””๋ฏธํ„ฐ์˜ ๋ฒ•์น™์„ ์ค€์ˆ˜ํ•จ์œผ๋กœ์จ ๊ฐ์ฒด์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๊ณ  ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ํ•˜๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์ฐธ๊ณ 

  1. https://1kevinson.com/the-law-of-demeter/
  2. https://mangkyu.tistory.com/147
  3. ํด๋ฆฐ์ฝ”๋“œ 6์žฅ

๋Œ“๊ธ€