[Book] ํด๋ฆฐ์ฝ”๋“œ - 7์žฅ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ

2021. 1. 14. 13:14ยท๐Ÿ“ Book/โœ Clean Code

7์žฅ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ

๋ญ”๊ฐ€ ์ž˜๋ชป๋  ๊ฐ€๋Šฅ์„ฑ์€ ๋Š˜ ์กด์žฌํ•œ๋‹ค.
๋ญ”๊ฐ€ ์ž˜๋ชป๋˜๋ฉด ๋ฐ”๋กœ ์žก์„ ์ฑ…์ž„์€ ๋ฐ”๋กœ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๊นจ๋—ํ•œ ์ฝ”๋“œ์™€ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๊ฐ€ ๊ด€๋ จ์ด ์žˆ์„๊นŒ? ํ™•์‹คํžˆ ์—ฐ๊ด€์„ฑ์ด ์žˆ๋‹ค.

์ƒ๋‹น์ˆ˜ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์€ ์ „์ ์œผ๋กœ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ์ฝ”๋“œ์— ์ขŒ์šฐ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ ์ขŒ์šฐ๋œ๋‹ค๋Š” ํ‘œํ˜„์€ ์ฝ”๋“œ ๊ธฐ๋ฐ˜์ด ์˜ค๋ฅ˜๋งŒ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ์˜๋ฏธ๊ฐ€ ์•„๋‹Œ ์—ฌ๊ธฐ์ €๊ธฐ ํฉ์–ด์ง„ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ์ฝ”๋“œ ๋•Œ๋ฌธ์— ์‹ค์ œ ์ฝ”๋“œ๊ฐ€ ํ•˜๋Š” ์ผ์„ ํŒŒ์•…ํ•˜๊ธฐ๊ฐ€ ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋Š” ์ค‘์š”ํ•˜์ง€๋งŒ ์ด ์ฝ”๋“œ๋กœ ์ธํ•ด ํ”„๋กœ๊ทธ๋žจ ๋…ผ๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค๋ฉด ๊นจ๋—ํ•œ ์ฝ”๋“œ๋ผ ๋ถ€๋ฅด๊ธฐ ์–ด๋ ต๋‹ค.

 

1. ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ณด๋‹ค ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๊ฐ€ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•,

์˜ค๋ฅ˜ ํ”Œ๋ž˜๊ทธ๋ฅผ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ํ˜ธ์ถœ์ž์—๊ฒŒ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์ „๋ถ€์˜€๋‹ค.

public void sendShutDown() {
    DeviceHandle handle = getHandle(DEV1);
    // Check the state of the device
    if (handle != DeviceHandle.INVALID) {
        // Save the device status to the record field
        retrieveDeviceRecord(handle);
        // If not suspended, shut down
        if (record.getStatus() != DEVICE_SUSPENDED) {
            pauseDevice(handle);
            clearDeviceWorkQueue(handle);
            closeDevice(handle);
        }
        else {
            logger.log("Device suspended. Unable to shut down");
        }
    }
    else {
        logger.log("Invalid handle for: " + DEV1.toString());
    }
}

๊ทธ๋Ÿฌ๋‚˜ ์œ„์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์€ ํ˜ธ์ถœ์ž ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ์žŠ์–ด๋ฒ„๋ฆฌ๊ธฐ ์‰ฝ๋‹ค.

 

๊ทธ๋ž˜์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ํŽธ์ด ๋‚ซ๋‹ค.

public void sendShutDown() {
  try {
    tryToShutDown();
  } catch (DeviceShutDownError e) {
    logger.log(e);
  }
}

๋””๋ฐ”์ด์Šค๋ฅผ ์ข…๋ฃŒํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ ์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋ถ„๋ฆฌํ•˜์—ฌ ์ฝ”๋“œ ํ’ˆ์งˆ์ด ์ข‹์•„์กŒ๋‹ค!

์ด์ œ๋Š” ๊ฐ ๊ฐœ๋…์„ ๋…๋ฆฝ์ ์œผ๋กœ ์‚ดํŽด๋ณด๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2. Try-Catch-Finally ๋ฌธ๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๋ผ

try-catch-finally ๋ฌธ์—์„œ try ๋ธ”๋ก์— ๋“ค์–ด๊ฐ€๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ด๋А ์‹œ์ ์—์„œ๋“  ์‹คํ–‰์ด ์ค‘๋‹จ๋œ ํ›„ catch ๋ธ”๋ก์œผ๋กœ ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ๋‹ค. try ๋ธ”๋ก์—์„œ ๋ฌด์Šจ ์ผ์ด ์ƒ๊ธฐ๋“  catch ๋ธ”๋ก์€ ํ”„๋กœ๊ทธ๋žจ ์ƒํƒœ๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•  ์ฝ”๋“œ๋ฅผ ์งค ๋•Œ๋Š” try-catch-finally ๋ฌธ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ํŽธ์ด ๋‚ซ๋‹ค.

 

3. ๋ฏธํ™•์ธ(Unchecked) ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

์˜ˆ์ „์—๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ๋•Œ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•  ์˜ˆ์™ธ๋ฅผ ๋ชจ๋‘ ์—ด๊ฑฐํ–ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๋น„์šฉ์ด ์ƒ์‘ํ•˜๋Š” ์ด์ต์„ ์ œ๊ณตํ•˜์ง€ ๋ชปํ–ˆ๊ณ  ํ™•์ธ๋œ ์˜ˆ์™ธ๋Š” OCP๋ฅผ ์œ„๋ฐ˜ํ•œ๋‹ค.

 

4. ์˜ˆ์™ธ์— ์˜๋ฏธ๋ฅผ ์ œ๊ณตํ•˜๋ผ

์˜ˆ์™ธ๋ฅผ ๋˜์งˆ ๋•Œ๋Š” ์ „ํ›„ ์ƒํ™ฉ์„ ์ถฉ๋ถ„ํžˆ ๋ง๋ถ™์ธ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์›์ธ๊ณผ ์œ„์น˜๋ฅผ ์ฐพ๊ธฐ๊ฐ€ ์‰ฌ์›Œ์ง„๋‹ค.

์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์— ์ •๋ณด๋ฅผ ๋‹ด์•„ ์˜ˆ์™ธ์™€ ํ•จ๊ป˜ ๋˜์ง„๋‹ค. ์‹คํŒจํ•œ ์—ฐ์‚ฐ ์ด๋ฆ„๊ณผ ์‹คํŒจ ์œ ํ˜•๋„ ์–ธ๊ธ‰ํ•œ๋‹ค.

 

5. ํ˜ธ์ถœ์ž๋ฅผ ๊ณ ๋ คํ•ด ์˜ˆ์™ธ ํด๋ž˜์Šค๋ฅผ ์ •์˜ํ•˜๋ผ

์˜ค๋ฅ˜๋ฅผ ๋ถ„๋ฅ˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ˆ˜์—†์ด ๋งŽ๊ณ  ๊ทธ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์œ„์น˜, ์œ ํ˜• ๋“ฑ์ด ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์˜ค๋ฅ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ด€์‹ฌ์‚ฌ๋Š” ์˜ค๋ฅ˜๋ฅผ ์žก์•„๋‚ด๋Š” ๋ฐฉ๋ฒ•์ด ๋˜์–ด์•ผ ํ•œ๋‹ค.

 

์•„๋ž˜ ๋ฐฉ๋ฒ•์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋˜์งˆ ์˜ˆ์™ธ๋ฅผ ๋ชจ๋‘ ์žก์•„๋‚ธ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ฝ”๋“œ ์ค‘๋ณต์ด ์‹ฌํ•˜๊ณ  ๋ณ€๊ฒฝํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

ACMEPort port = new ACMEPort(12);
try {
	port.open();
}
catch (DeviceResponseException e) {
	reportPortError(e);
	logger.log("Device response exception", e);
}
catch (ATM1212UnlockedException e) {
	reportPortError(e);
	logger.log("Unlock exception", e);
}
catch (GMXError e) {
	reportPortError(e);
	logger.log("Device response exception");
}
finally {
	...
}

 

๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ํ˜ธ์ถœํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ API๋ฅผ ๊ฐ์‹ธ๋ฉด์„œ ์˜ˆ์™ธ ์œ ํ˜• ํ•˜๋‚˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

LocalPort ํด๋ž˜์Šค๋ฅผ ๋‹จ์ˆœํžˆ ACMEPort ํด๋ž˜์Šค๊ฐ€ ๋˜์ง€๋Š” ์˜ˆ์™ธ๋ฅผ ์žก์•„ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฐ์‹ธ๊ธฐ(Wrapper) ํด๋ž˜์Šค์ด๋‹ค.

Wrapper ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์˜์กด์„ฑ์ด ํฌ๊ฒŒ ์ค„์–ด๋“ค๊ณ  ๋‚˜์ค‘์— ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๊ฐˆ์•„ํƒ€๋„ ๋น„์šฉ์ด ์ ๋‹ค.

LocalPort port = new LocalPort(12);
try {
    port.open();
}
catch (PortDeviceFailure e) {
    reportError(e);
    logger.log(e.getMessage(), e);
}
finally {
    ...
}

public class LocalPort {
    private ACMEPort innerPort;
    public LocalPort(int portNumber) {
        innerPort = new ACMEPort(portNumber);
    }

    public void open() {
        try {
            innerPort.open();
        }
        catch (DeviceResponseException e) {
            throw new PortDeviceFailure(e);
        }
        catch (ATM1212UnlockedException e) {
            throw new PortDeviceFailure(e);
        }
        catch (GMXError e) {
            throw new PortDeviceFailure(e);
        }
    }
}

 

6. null์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ๋งˆ๋ผ

nulll์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ผ๊ฑฐ๋ฆฌ๋ฅผ ๋Š˜๋ฆด ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ˜ธ์ถœ์ž์—๊ฒŒ ๋ฌธ์ œ๋ฅผ ๋– ๋„˜๊ธด๋‹ค.

public void registerItem(Item item) {
    if (item != null) {
        ItemRegistry registry = peristentStore.getItemRegistry();
        if (registry != null) {
            Item existing = registry.getItem(item.getID());
            if (existing.getBillingPeriod().hasRetailOwner()) {
                existing.register(item);
            }
        }
    }
}

 

7. null์„ ์ „๋‹ฌํ•˜์ง€ ๋งˆ๋ผ

๋ฉ”์„œ๋“œ์—์„œ null์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹๋„ ๋‚˜์˜์ง€๋งŒ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์€ ๋” ๋‚˜์˜๋‹ค.

// Parameter์— null๊ฐ’์ด ๋“ค์–ด์˜ค๋ฉด NullPointerException ๋ฐœ์ƒ
public class MetricsCalculator {
    public double xProjection(Point p1, Point p2) {
        return (p2.x – p1.x) * 1.5;
    }
}

// InvalidArgumentException ์‚ฌ์šฉ: ์œ„ ๋ฐฉ๋ฒ•๋ณด๋‹จ ๋‚ซ๋‹ค.. ํ•˜์ง€๋งŒ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋‹˜
public class MetricsCalculator {
    public double xProjection(Point p1, Point p2) {
        if (p1 == null || p2 == null) {
            throw InvalidArgumentException("Invalid argument for MetricsCalculator.xProjection");
        }
        return (p2.x – p1.x) * 1.5;
    }
}

๋Œ€๋‹ค์ˆ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋Š” ํ˜ธ์ถœ์ž๊ฐ€ ์‹ค์ˆ˜๋กœ ๋„˜๊ธฐ๋Š” null์„ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—†๋‹ค.

์• ์ดˆ์— null์„ ๋„˜๊ธฐ์ง€ ์•Š๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹๋‹ค.

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)
'๐Ÿ“ Book/โœ Clean Code' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [Book] ํด๋ฆฐ์ฝ”๋“œ - 9์žฅ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ
  • [Book] ํด๋ฆฐ์ฝ”๋“œ - 8์žฅ ๊ฒฝ๊ณ„
  • [Book] ํด๋ฆฐ์ฝ”๋“œ - 6์žฅ ๊ฐ์ฒด์™€ ์ž๋ฃŒ ๊ตฌ์กฐ
  • [Book] ํด๋ฆฐ์ฝ”๋“œ - 5์žฅ ํ˜•์‹ ๋งž์ถ”๊ธฐ
Blxxming
Blxxming
CS ์ง€์‹๊ณผ ๊ณต๋ถ€ํ•˜๋‹ค ๋ฐฐ์šด ๊ฒƒ, ๊ฒฝํ—˜ํ•œ ๊ฒƒ ๋“ฑ์„ ๊ธฐ๋กํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
  • Blxxming
    ๐Ÿ’ก๋ฒˆ๋œฉ๐Ÿ’ก
    Blxxming
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
  • ๊ณต์ง€์‚ฌํ•ญ

    • Tech Interview
    • ๐Ÿ“š Tech (246)
      • ๐Ÿ“ Computer Science (96)
        • โœ OS (12)
        • โœ Network & Web (10)
        • โœ Database (11)
        • โœ Data Structure (6)
        • โœ Algorithm (40)
        • โœ Design Pattern (9)
        • โœ Cloud Computing (3)
        • โœ (5)
      • ๐Ÿ“ Language (73)
        • โœ Language (6)
        • โœ C & C++ (11)
        • โœ C# (19)
        • โœ JAVA (37)
      • ๐Ÿ“ Game (43)
        • โœ Computer Graphics (2)
        • โœ Unity (14)
        • โœ Unreal (26)
        • โœ (1)
      • ๐Ÿ“ Book (34)
        • โœ Effective (3)
        • โœ Game Server (16)
        • โœ Clean Code (14)
        • โœ (1)
  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.0
Blxxming
[Book] ํด๋ฆฐ์ฝ”๋“œ - 7์žฅ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”