λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

πŸ“šμ½μ€ μ±… 정리/μžλ°” μ½”λ”©μ˜ 기술

[μžλ°” μ½”λ”©μ˜ 기술] 4μž₯ : μ˜¬λ°”λ₯΄κ²Œ λͺ…λͺ…ν•˜κΈ°

ν”„λ‘œκ·Έλž˜λ°μ—μ„œ 이름을 μ˜¬λ°”λ₯΄κ²Œ μ§“λŠ” 것은 μ€‘μš”ν•˜λ‹€. ν•˜μ§€λ§Œ νŒ¨ν‚€μ§€, 클래슀, λ©”μ„œλ“œ, ν•„λ“œ, λ§€κ°œλ³€μˆ˜, 지역 λ³€μˆ˜ λ“± λͺ…λͺ…ν•  μš”μ†Œκ°€ λ„ˆλ¬΄ 많기 λ•Œλ¬Έμ— λͺ¨λ“  μš”μ†Œμ— 쒋은 이름을 μ§“λŠ” 것은 μ–΄λ ΅λ‹€. 4μž₯μ—μ„œλŠ” μ½”λ“œ μš”μ†Œμ— κ±Έλ§žλŠ” 이름을 ν• λ‹Ήν•˜λŠ” 방법에 λŒ€ν•΄μ„œ λ°°μš΄λ‹€.

 

λͺ…λͺ…ν•  땐 μžλ°” κ·œμΉ™μ΄ μ€‘μš”ν•˜λ©°, λ©”μ„œλ“œ λͺ…λͺ…은 κ°„κ²°ν•΄μ•Όλ§Œ ν•˜λ©° μ˜λ―Έμ—†κ±°λ‚˜ ν•œ κΈ€μžμ§œλ¦¬ 이름은 ν”Όν•΄μ•Όλ§Œ ν•œλ‹€.

4.1 μžλ°” λͺ…λͺ… κ·œμΉ™ μ‚¬μš©ν•˜κΈ°

μ•„λž˜ μ½”λ“œλŠ” μ–΄λ–€ λ¬Έμ œκ°€ μžˆμ„κΉŒ..?

class Rover {
    static final double WalkingSpeed = 3;

    final String SerialNumber;
    double MilesPerHour;

    Rover(String NewSerialNumber) {
        SerialNumber = NewSerialNumber;
    }

    void Drive() {
        MilesPerHour = WalkingSpeed;
    }
    void Stop() {
        MilesPerHour = 0;
    }
}

μƒμˆ˜, λ©”μ„œλ“œ, λ³€μˆ˜μ˜ 넀이밍을 μžμ„Ένžˆ ν™•μΈν•΄λ³΄μž.

 

μˆ˜μ •ν•΄μ•Ό ν•˜λŠ” 것

- μžλ°” μ½”λ“œ κ·œμΉ™μ— 따라 μ²«μ‹œμž‘μ€ μ†Œλ¬Έμžλ‘œ κ·Έλ‹€μŒ μ‹œμž‘ λ‹¨μ–΄λŠ” λŒ€λ¬Έμžλ‘œ ν•©λ‹ˆλ‹€. 

- μƒμˆ˜λŠ” λ‘λ“œλŸ¬μ§€κ²Œ ν‘œν˜„ -> λͺ¨λ“  철자λ₯Ό λŒ€λ¬Έμž + '_'λ₯Ό 톡해 단어 이음

- λ³€μˆ˜λŠ” λͺ…μ‚¬λ‘œ ν‘œν˜„, λ©”μ„œλ“œλŠ” λ™μ‚¬μ˜ ν˜•νƒœλ₯Ό μ·¨ν•˜κ±°λ‚˜ <is, has, save, get, set> 등을 μ΄μš©ν•΄ λ™μ‚¬λ‘œ μ‹œμž‘ν•΄μ•Όν•œλ‹€.

 

μˆ˜μ • μ½”λ“œ

class Rover {
    static final double WALKING_SPEED = 3;

    final String serialNumber;
    double milesPerHour;

    Rover(String serialNumber) {
        this.serialNumber = serialNumber;
    }

    void drive() {
        milesPerHour = WALKING_SPEED;
    }

    void stop() {
        milesPerHour = 0;
    }
}

 

4.2 ν”„λ ˆμž„μ›Œν¬μ—λŠ” Getter/Setter κ·œμΉ™ 적용

객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ—μ„œλŠ” μ™ΈλΆ€μ—μ„œ 클래슀 ν•„λ“œμ— 직접 μ ‘κ·Όν•˜λŠ” 것을 μ œν•œν•˜κΈ° μœ„ν•΄ κ²Œν„°μ™€ μ„Έν„° λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•œλ‹€.

 

μ΄λŸ¬ν•œ κ²Œν„°, μ„Έν„° λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄ 'ν•˜μ΄λ²„λ„€μ΄νŠΈ', '잭슨' λ“±μ˜ ν”„λ ˆμž„μ›Œν¬μ—μ„œλŠ” 각자의 κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κ³  μžˆλ‹€. λ”°λΌμ„œ, κ²Œν„°, μ„Έν„° μž‘μ„± μ‹œ λ§ˆμŒλŒ€λ‘œ 이름 μ§€μœΌλ©΄ μ•ˆλ˜κ³  'μžλ°” 빈' λͺ…μ„Έλ₯Ό 따라야 ν•œλ‹€.

class Astronaut {
    private String name;
    private boolean retired;

    public Astronaut() {
    }

    public Astronaut(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isRetired() {
        return retired;
    }

    public void setRetired(boolean retired) {
        this.retired = retired;
    }

}

- κ²Œν„°, μ„Έν„°λ₯Ό μ‚¬μš©ν•  λ³€μˆ˜λͺ… μ•žμ— getκ³Ό set을 뢙이고 λ³€μˆ˜μ˜ 첫번째 μ² μžλŠ” λŒ€λ¬Έμžλ‘œ λ§Œλ“ λ‹€.

- 'Boolean' νƒ€μž…μ€ κ²Œν„°μ˜ κ²½μš°μ—λ§Œ getRetired() λŒ€μ‹ μ— isRetired() ν˜•νƒœλ‘œ μž‘μ„±ν•œλ‹€.

4.3 ν•œ κΈ€μžλ‘œ λͺ…λͺ…ν•˜μ§€ μ•ŠκΈ°

class Inventory {
    List<Supply> sl = new ArrayList<>();

    boolean isInStock(String n) {
        Supply s = new Supply(n);
        int l = 0; // 쒋지 μ•Šμ€ λ³€μˆ˜λͺ….....
        int h = sl.size() - 1;

        while (l <= h) {
            int m = l + (h - l) / 2;
            int c = sl.get(m).compareTo(s);

            if (c < 0) {
                l = m + 1;
            } else if (c > 0) {
                h = m - 1;
            } else {
                return true;
            }
        }

        return false;
    }
}

μœ„ μ½”λ“œ 처럼 λ³€μˆ˜λͺ…을 ν•œ κΈ€μžλ‘œ ν‘œν˜„ν•˜λ©΄ λ³€μˆ˜κ°€ μ–΄λ–€ μ˜λ―ΈμΈμ§€ 머릿속에 항상 κΈ°μ–΅ν•˜κ³  μžˆμ–΄μ•Ό ν•œλ‹€. μ΄λ ‡κ²Œ 되면 λ©”μ„œλ“œκ°€ μ–΄λ–€ 역할을 ν•˜λŠ”μ§€λ„ μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œμ§€κ³  전체 μ½”λ“œ λ§₯락 λ˜ν•œ μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œμ§„λ‹€.

 

λ³€μˆ˜λ₯Ό 머릿속에 κΈ°μ–΅ν•˜μ§€ 말고 κ·Έλƒ₯ μ½”λ“œμ— "전체 이름"을 λͺ…ν™•ν•˜κ²Œ μž‘μ„±ν•˜μž.

μ–΄μ°¨ν”Ό 컴퓨터가 μ΄ν•΄ν•˜λŠ” λ°”μ΄νŠΈμ½”λ“œμ—μ„œ "ν•œ κΈ€μž"와 "전체 이름"의 μ°¨μ΄λŠ” μ—†λ‹€.

4.4 μΆ•μ•½ 쓰지 μ•ŠκΈ°

μΆ•μ•½μ΄λ‚˜ ν•œ κΈ€μž μ“°κΈ°λ‚˜ λ˜‘κ°™λ‹€. μžμ‹ λ§Œ 이해할 수 μžˆλŠ” μ•”ν˜Έμ΄λ©° λ‹€λ₯Έ μ‚¬λžŒμ€ 이λ₯Ό ν•΄μ„ν•˜λŠ” μ• λ₯Ό 먹을 것이닀.

 

λ”°λΌμ„œ, 정말 ν”νžˆ μ“°μ΄λŠ” μΆ•μ•½ ν‘œν˜„μ„ μ œμ™Έν•˜κ³ λŠ” λ°˜λ“œμ‹œ "전체 이름"을 μ‚¬μš©ν•˜μž.

 

- 문제 μ½”λ“œ

class Logbook {
    static final Path DIR = Paths.get("/var/log");
    static final Path CSV = DIR.resolve("stats.csv");
    static final String GLOB = "*.log";

    void createStats() throws IOException {
        try (DirectoryStream<Path> dirStr =
                     Files.newDirectoryStream(DIR, GLOB);
             BufferedWriter bufW = Files.newBufferedWriter(CSV)) {
            for (Path lFile : dirStr) {
                String csvLn = String.format("%s,%d,%s",
                        lFile,
                        Files.size(lFile),
                        Files.getLastModifiedTime(lFile));
                bufW.write(csvLn);
                bufW.newLine();
            }
        }
    }
}

 

<κ°œμ„  μ½”λ“œ>

class Logbook {
    static final Path LOG_FOLDER = Paths.get("/var/log");
    static final Path STATISTICS_CSV = LOG_FOLDER.resolve("stats.csv");
    static final String FILE_FILTER = "*.log";

    void createStatistics() throws IOException {
        try (DirectoryStream<Path> logs =
                     Files.newDirectoryStream(LOG_FOLDER, FILE_FILTER);
             BufferedWriter writer =
                     Files.newBufferedWriter(STATISTICS_CSV)) {
            for (Path log : logs) {
                String csvLine = String.format("%s,%d,%s",
                        log,
                        Files.size(log),
                        Files.getLastModifiedTime(log));
                writer.write(csvLine);
                writer.newLine();
            }
        }
    }
}

4.5 λ¬΄μ˜λ―Έν•œ μš©μ–΄ 쓰지 μ•ŠκΈ°

"ν•œ κΈ€μž 쓰지 μ•ŠκΈ°", "μΆ•μ•½ μ‚¬μš©ν•˜μ§€ μ•ŠκΈ°" 만 보면 무쑰건 ν’€μ–΄μ“΄ μ½”λ“œκ°€ 쒋은 κ²ƒμ²˜λŸΌ 보인닀. ν•˜μ§€λ§Œ 그건 μ•„λ‹ˆλ‹€..

μš°λ¦¬λŠ” μ‚­μ œ 해도 λ˜λŠ” 'λ¬΄μ˜λ―Έν•œ' 단어λ₯Ό μ°Ύμ•„μ„œ μ—†μ• μ•Ό ν•œλ‹€. 

 

문제 μ½”λ“œ

class MainSpaceShipManager {
    AbstractRocketPropulsionEngine abstractRocketPropulsionEngine;
    INavigationController navigationController;
    boolean turboEnabledFlag;

    void navigateSpaceShipTo(PlanetInfo planetInfo) {
        RouteData data = navigationController.calculateRouteData(planetInfo);
        LogHelper.logRouteData(data);
        abstractRocketPropulsionEngine.invokeTask(data, turboEnabledFlag);
    }
}

ν•΄κ²° 방법

  1. 자주 μ“°μ΄λŠ” λ¬΄μ˜λ―Έν•œ μš©μ–΄ μ°Ύμ•„μ„œ μ—†μ• κΈ° ("main", "flag", "data", "info" λ“±)
  2. νƒ€μž…μ΄λ‚˜ λ©”μ„œλ“œ λͺ…에 λ“€μ–΄μžˆλŠ” λ‹Ήμ—°ν•œ μš©μ–΄λ“€ ("abstract", "invoke(λ°œλ™)", "Call")
  3. 클래슀λͺ…이 이미 μ•Œλ €μ£Όκ³  μžˆλŠ” μ •λ³΄λŠ” 클래슀 λ‚΄ λ³€μˆ˜λ‚˜ λ©”μ„œλ“œμ—μ„œ 또 μ•Œλ €μ£Όμ§€ μ•Šμ•„λ„ λœλ‹€.

κ°œμ„  μ½”λ“œ

class SpaceShip {
    Engine engine;
    Navigator navigator;
    boolean turboEnabled;

    void navigateTo(Planet destination) {
        Route route = navigator.calculateRouteTo(destination);
        Logger.log(route);
        engine.follow(route, turboEnabled);
    }
}

λ³€μˆ˜μ™€ λ©”μ„œλ“œμ˜ 역할을 μ΄ν•΄ν• μˆ˜ μžˆμœΌλ©΄μ„œ 훨씬 μ½”λ“œκ°€ κ°„κ²°ν•΄μ‘Œλ‹€.

4.6 도메인 μš©μ–΄ μ‚¬μš©ν•˜κΈ°

개발 쀑인 λŒ€λΆ€λΆ„μ˜ μ½”λ“œλŠ” νŠΉμ • 도메인에 μ†ν•˜κ²Œ 되고 도메인 λ§ˆλ‹€ 각각의 μ–΄νœ˜λ₯Ό 가진닀.

 

예λ₯Ό λ“€μ–΄, μŠ€ν¬μΈ μ—μ„œ 'μ‹€λ°₯μ΄μžˆλŠ” 곡'은 야ꡬ이고 'μ‹€λ°₯이 μ—†μœΌλ©΄μ„œ νŠ€λŠ” 볼은' 좕ꡬ곡일 것이닀.

 

이처럼 ν”„λ‘œκ·Έλž¨μ— ν•΄λ‹Ήν•˜λŠ” 도메인 μš©μ–΄λ₯Ό μ½”λ“œμ— 많이 넣을 수둝 μ½”λ“œλŠ” 점점 쒋아진닀.

문제 μ½”λ“œ

class Person {
    String lastName;
    String role;
    int travels;
    LocalDate employedSince;

    String serializeAsLine() {
        return String.join(",",
                Arrays.asList(lastName,
                        role,
                        String.valueOf(travels),
                        String.valueOf(employedSince))
        );
    }
}

κ°œμ„  μ½”λ“œ

class Astronaut {
    String tagName; // μš°μ£ΌλΉ„ν–‰μ‚¬μ—κ²Œ νŠΉν™”λœ 넀이밍
    String rank;
    int missions;
    LocalDate activeDutySince;

    String toCSV() {
        return String.join(",",
                Arrays.asList(tagName,
                        rank,
                        String.valueOf(missions),
                        String.valueOf(activeDutySince))
        );
    }
}

μš°μ£ΌλΉ„ν–‰μ‚¬ ν•„λ“œμ— λŒ€ν•œ μ˜λ―Έμ™€ 이해도가 훨씬 κ°œμ„ λœλ‹€.

4.7 4μž₯μ—μ„œ 배운 λ‚΄μš©

λͺ…λͺ…은 잘λͺ»ν•΄λ„ μ»΄νŒŒμΌμ€ λ˜μ§€λ§Œ μ½”λ“œλ₯Ό 읽고 μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œμ§„λ‹€.

 

μ΄λŠ” μ½”λ“œ μœ μ§€λ³΄μˆ˜λ₯Ό 정말 μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€.

 

κΌ­ λͺ…λͺ… κ·œμΉ™μ„ 지킀렀고 λ…Έλ ₯ν•˜λ©΄μ„œ κ°œλ°œν•˜λ„λ‘ ν•˜μž.