๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿคท๐Ÿผ‍โ™€๏ธ Etc.../- ๊ธฐํƒ€

[๊ฐœ๋ฐœ์ž ์ฑ…์ฝ๊ธฐ] ํด๋ฆฐ ์ฝ”๋“œ-์• ์ž์ผ ์†Œํ”„ํŠธ์›จ์–ด ์žฅ์ธ ์ •์‹  (6์žฅ ๊ฐ์ฒด์™€ ์ž๋ฃŒ๊ตฌ์กฐ)

by Wonit 2022. 2. 18.

ํ•ด๋‹น ๊ธ€์€ Robert C.Martin ํด๋ฆฐ ์ฝ”๋“œ ๋ผ๋Š” ์ฑ…์„ ์ฝ๊ณ  ํ•™์Šตํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ ํ•˜๋Š” ๊ธ€ ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ YES 24 ํด๋ฆฐ ์ฝ”๋“œ - ์• ์ž์ผ ์†Œํ”„ํŠธ์›จ์–ด ์žฅ์ธ ์ •์‹  ์—์„œ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

 

ํด๋ฆฐ ์ฝ”๋“œ - ์• ์ž์ผ ์†Œํ”„ํŠธ์›จ์–ด ์žฅ์ธ ์ •์‹  (Uncle Bob)

 

  • ์œ„ํ‚ค๋ถ์Šค
  • ์ง€์€์ด: Robert C.Martin (Uncle Bob)
  • ์˜ฎ๊ธด์ด: ๋ฐ•์žฌํ˜ธ, ์ดํ•ด์˜

 

 


 

์ด๋ฒˆ ์žฅ์—์„œ ์ด์•ผ๊ธฐํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ

 

  • ์ž๋ฃŒ ์ถ”์ƒํ™”
    • private ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ๋†“๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ผ๊นŒ?
      • private ์œผ๋กœ ๋ณ€์ˆ˜ ์ ‘๊ทผ์„ ์ œํ•œํ•˜์—ฌ ๋ฐ์ดํ„ฐ (๋ณ€์ˆ˜)์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
    • ๋ณ€์ˆ˜๋ฅผ private ์œผ๋กœ ๊ฐ์ถ”์–ด๋„ ์กฐํšŒ ํ•จ์ˆ˜์™€ ์„ค์ • ํ•จ์ˆ˜ getter/setter ๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋Š”๊ฒƒ ๋งŒ์œผ๋กœ๋„ ์™ธ๋ถ€๋กœ ๋…ธ์ถœํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค.
    • ๋‹น์—ฐํ•˜๊ฒŒ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์˜ค๋กœ์ง€ ํ•จ์ˆ˜๋ผ๋Š” ๊ณ„์ธต์„ ๋„ฃ๋Š”๋‹ค๊ณ  ํ•ด์„œ ๊ฐ์ถฐ์ง€๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
    • ์ถ”์ƒ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌํ˜„์„ ๋ชจ๋ฅธ ์ฑ„ ํ•ต์‹ฌ์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
    • ์ž๋ฃŒ๋ฅผ ์„ธ์„ธํ•˜๊ฒŒ ๊ณต๊ฐœํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์ถ”์ƒ์ ์ธ ๊ฐœ๋…์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค
    • ์ค‘์š”ํ•œ ๊ฒƒ์€ ํŠน์ • ํ–‰๋™์„ ์ถ”๊ฐ€ํ•˜๋”๋ผ๋„ ๊ธฐ์กด์˜

 

interface Person {
  String getInformation();
}

class Teacher implements Person {

  private String name;
  private int age;

  public String getName() {} // getter => public ๊ณผ ๊ฐ™๋‹ค

  public int getAge() {}

  @Override
  public String getInformation() { // => ๊ตฌํ˜„์„ ๋ชจ๋ฅธ์ฑ„ ํ•ต์‹ฌ์„ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค.
    return name + " " + age; // ๋ฐ์ดํ„ฐ์— ์˜์กด์ ์ด์ง€ ์•Š๊ฒŒ ๋œ๋‹ค
  }
}

 

์ ˆ์ฐจ์ง€ํ–ฅ๊ณผ ๊ฐ์ฒด์ง€ํ–ฅ

 

  • ์ ˆ์ฐจ์ง€ํ–ฅ
    • ์ฐธ์กฐ ์—ฐ์ž”์‚ฌ๋ฅผ ํ†ตํ•ด์„œ ์–ด๋– ํ•œ ํ•จ์ˆ˜๋˜ ์ถ”๊ฐ€์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋”๋ผ๋„ ๋ฌด๋ฆฌ๊ฐ€ ์—†๋‹ค.
    • ์ฆ‰, ๊ธฐ์กด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ƒˆ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‰ฝ๋‹ค.
    • ๋˜ํ•œ ์ƒˆ๋กœ์šด ํ˜•์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์–ด๋ ต๋‹ค

 

public class Square {
  public int width;
  public int height;
}
public class Circle {
  public int radius;
  public int circle;
}

public class Main {

  Square s = new Square();

  public int ares(String type) {
    if (type.equals("Square")) {
      return s.width * s.height;
    } else if (type.equals("Circle")) {
      return PI * radius * radius;
    }
    // ...
  }
}

 

  • ๊ฐ์ฒด์ง€ํ–ฅ
    • Polymorphic ์„ ํ†ตํ•ด ์ƒˆ๋กœ์šด ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š”๋ฐ ์ œ์•ฝ์ด ์—†๋‹ค.
    • ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ์‹ถ๋‹ค๋ฉด Shape ์˜ ๊ตฌํ˜„์ฒด ๋ชจ๋‘์—๊ฒŒ ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค
    • ์ฆ‰, ๊ธฐ์กด์˜ ํ•จ์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ์ƒˆ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์‰ฝ๋‹ค.
    • ๋˜ํ•œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์–ด๋ ต๋‹ค

 

public class Shape {
  public int area();
}

public class Square implements Shape {
  @Override
  public int area() {
    return // ..
  }
}

public class Circle implements Shape {
  @Override
  public int area() {
    return // ..
  }
}

 

์œ„์˜ ๋‚ด์šฉ์œผ๋กœ ๋ฏธ๋ฃจ์–ด ๋ณด์•˜์„ ๋•Œ, ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ๊ฐ์ฒด์ง€ํ–ฅ์ด๋ผ๊ณ  ํ•ด์„œ ์ข‹์€ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

 

์ ˆ์ฐจ์ง€ํ–ฅ์˜ ์ฝ”๋“œ๊ฐ€ ํšจ์œจ์ ์ธ ๊ณณ์ด ์กด์žฌํ•œ๋‹ค.

 

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

 

  • ๋””๋ฏธํ„ฐ ๋ฒ•์น™
    • ๊ฐ์ฒด์ง€ํ–ฅ์˜ ๊ธฐ๋ณธ์œผ๋กœ ํ•œ ์ค„์— ํ•œ ์  ์ฐ๊ธฐ๋กœ ์œ ๋ช…ํ•œ ๋ฒ•์น™
    • ๊ฐ์ฒด๋Š” ์Šค์Šค๋กœ๊ฐ€ ๋ณด์œ ํ•œ ์ •๋ณด๋กœ๋งŒ ๊ฐ€์ง€๊ณ  ์˜์‚ฌ ๊ฒฐ์ •์„ ํ•ด์•ผํ•œ๋‹ค.
    • ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ํƒ์ƒ‰ํ•ด ๋ฌด์–ธ๊ฐ€๋ฅผ ์•Œ์•„๋‚ด์„œ๋Š” ์•ˆ๋œ๋‹ค.

 

  • ๊ธฐ์ฐจ ์ถฉ๋Œ
    • ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ์–ด๊ธด ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€
    • ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋“ค์ด ํ•œ ์ค„๋กœ ์ด์–ด์ง„ ํ˜•ํƒœ์˜ ๋ฐฉ์‹์˜ ๊ฐœ๋ฐœ์„ ์ผ์ปซ๋Š”๋‹ค.
      • ํ•˜์ง€๋งŒ ๋‹จ์ˆœ ์ž๋ฃŒ ๊ตฌ์กฐ (DTO) ์ธ ๊ฒฝ์šฐ ๋””๋ฏธํ„ฐ ๋ฒ•์น™์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค.
      • ๊ฐ์ฒด์˜ ๊ฒฝ์šฐ๋ผ๋ฉด ๋””๋ฏธํ„ฐ ๋ฒ•์น™์ด ์ ์šฉ๋œ๋‹ค.

 

// ๊ธฐ์ฐจ ์ถฉ๋Œ ์ฝ”๋“œ์ง€๋งŒ ๋‹จ์ˆœ ์ž๋ฃŒ ๊ตฌ์กฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฏธํ„ฐ ๋ฒ•์น™์ด ์ ์šฉ๋˜์ง€ ์•Š์Œ
String title = envelopeNotification.getNotification().getSubject().getValue();

// ๊ธฐ์ฐจ ์ถฉ๋Œ ์ฝ”๋“œ์ด๋ฉฐ ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋””๋ฏธํ„ฐ ๋ฒ•์น™์„ ๋ฒ—์–ด๋‚จ
String title = boardService.findPostingById(1004L).getBody().getTitle();

 

๋‚˜์˜ ํ•ด์„๊ณผ ํšŒ๊ณ 

 

์–ด๋–ค ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ์–ธ๋œป ๋ณด๊ธฐ์— ์ž๋ฃŒ ๊ตฌ์กฐ์ฒ˜๋Ÿผ ์ƒ๊ธด ๊ฐ์ฒด๊ฐ€ ์žˆ์—ˆ๋‹ค.

 

ํ•ด๋‹น ๊ฐ์ฒด๋Š” ์—ฌ๋Ÿฌ ๊ตฌํ˜„์ฒด๋“ค์ด ์กด์žฌํ•˜๋ฉฐ ๊ตฌํ˜„์ฒด๋“ค๋งˆ๋‹ค ๊ฐ๊ฐ ํ‘œํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” ์„ธ๋ถ€ ๋‚ด์šฉ์ด ์กฐ๊ธˆ ๋‹ฌ๋ž๋‹ค.

 

๊ทธ ๊ฐ์ฒด์—์„œ๋Š” ์ถ”์ƒ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด์„œ Client ๋Š” ๊ตฌํ˜„์„ ์•Œ์ง€ ๋ชปํ•œ ์ฑ„, ํ•ต์‹ฌ๋งŒ ์กฐ์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ–ˆ๋‹ค.

 

์‚ฌ์‹ค ๋‚˜๋Š” ์ฒ˜์Œ ์ฝ”๋“œ๋ฅผ ๋ณด์•˜์„ ๋•Œ, ์ง๊ด€์ ์œผ๋กœ ์ดํ•ด๊ฐ€ ๊ฐ€์ง€ ์•Š์•˜์—ˆ๊ณ  ํฌ๊ฒŒ ์™€๋‹ฟ์ง€ ์•Š์•˜๋‹ค.

 

ํ•˜์ง€๋งŒ ์ด์ œ์„œ์•ผ ๊ทธ๊ฒƒ์ด ์–ด๋–ค ์˜๋ฏธ์ธ์ง€, Client ๋Š” ๊ตฌํ˜„์„ ์•Œ์ง€ ๋ชปํ•œ ์ฑ„, ํ•ต์‹ฌ๋งŒ ์กฐ์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

๊ฐ„๋‹จํžˆ ๋‚ด์šฉ์„ ์„ค๋ช…ํ•˜์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

interface ResultTarget {
  String getId();
}

class KakaoResultTarget implements ResultTarget {
  private String username;
  private LocalDateTime createdAt;

  @Override
  public String getId() {
    return username + createdAt.toString() + Math.random();
  }
}

class NaverResultTarget implements ResultTarget {
  private String nickname;
  private Long userId;

  @Override
  public String getId() {
    return nickname + "&" + userId + Math.random();
  }
}

์ด๋ ‡๊ฒŒ ํด๋ผ์ด์–ธํŠธ๋Š” ๊ตฌํ˜„์„ ์•Œ์ง€ ๋ชปํ•œ ์ฑ„, ํ•ต์‹ฌ๋งŒ ์กฐ์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.

 

์ฆ‰, ํด๋ผ์ด์–ธํŠธ๋Š” Kakao ์ด๋˜ Naver ์ด๋˜ ์ƒ๊ด€ ์—†์ด Id ๋ผ๋Š” ํ•„๋“œ๋งŒ์„ ์›ํ•˜๋Š” ์ƒํ™ฉ์ด๊ณ  ์ด๋ฅผ ์ถ”์ƒํ™” ํ•œ ๊ฒƒ์ด ๋ฐ”๋กœ ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ ธ์•ผ ํ•  ๊ธฐ๋ณธ์ ์ธ ์†Œ์–‘์ด ์•„๋‹๊นŒ ์‹ถ๋‹ค.

 

๋Œ“๊ธ€