๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“’ ๊ฐœ๋ฐœ ์„œ์ /Clean Code

[Clean Code] 7์žฅ ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ

by nitronium102 2022. 3. 5.

TIL (Today I Learned)

22.03.04~22.03.05

์˜ค๋Š˜ ์ฝ์€ ๋ฒ”์œ„

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

์ฑ…์—์„œ ๊ธฐ์–ตํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ

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

// ์˜ค๋ฅ˜ ์ฝ”๋“œ ์‚ฌ์šฉ
public void sendShutDown() {
	DeviceHandle handle = getHandle(DEV1);
	if (handle != DeviceHandle.INVALID) { ... }
}

// ์˜ˆ์™ธ ์‚ฌ์šฉ
public void sendShutDown() {
	try {
		DeviceHandle handle = getHandle(DEV1);
	} catch (DeviceShutDownError e) { 
    	logger.log(e);
    }
}

 

try-catch-finally ๋ฌธ๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๋ผ

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

 

ํ…Œ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ๋Š” ๊ฐ•์ œ๋กœ ์˜ˆ์™ธ๋ฅผ ์ผ์œผํ‚ค๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑํ•œ ํ›„ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ต๊ณผํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ถŒ์žฅํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ try ๋ธ”๋ก์˜ ํŠธ๋žœ์žญ์…˜ ๋ฒ”์œ„๋ถ€ํ„ฐ ๊ตฌํ˜„ํ•˜๊ฒŒ ๋˜๋ฏ€๋กœ ๋ฒ”์œ„ ๋‚ด์—์„œ ํŠธ๋žœ์žญ์…˜ ๋ณธ์งˆ์„ ์œ ์ง€ํ•˜๊ธฐ ์‰ฌ์›Œ์ง„๋‹ค.

 

๋ฏธํ™•์ธ ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ

checked exception์€ OCP๋ฅผ ์œ„๋ฐ˜ํ•œ๋‹ค. ํ•˜์œ„ ๋‹จ๊ณ„์—์„œ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ƒ์œ„ ๋‹จ๊ณ„ ๋ฉ”์„œ๋“œ ์„ ์–ธ๋ถ€์— ๋ชจ๋‘ ํ•ด๋‹น ์˜ˆ์™ธ๋ฅผ ์ •์˜ํ•ด์•ผ ํ•œ๋‹ค. ๋ชจ๋“ˆ๊ณผ ๊ด€๋ จ๋œ ์ฝ”๋“œ๊ฐ€ ์ „ํ˜€ ๋ฐ”๋€Œ์ง€ ์•Š์•˜์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  (์„ ์–ธ๋ถ€๊ฐ€ ๋ฐ”๋€Œ์—ˆ์œผ๋ฏ€๋กœ) ๋ชจ๋“ˆ์„ ๋‹ค์‹œ ๋นŒ๋“œํ•œ ๋‹ค์Œ ๋ฐฐํฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋ง์ด๋‹ค. 

 

throws ๊ฒฝ๋กœ์— ์œ„์น˜ํ•˜๋Š” ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ ์ตœํ•˜์œ„ ํ•จ์ˆ˜์—์„œ ๋˜์ง€๋Š” ์˜ˆ์™ธ๋ฅผ ์•Œ์•„์•ผ ํ•˜๋ฏ€๋กœ ์บก์Šํ™”๊ฐ€ ๊นจ์ง„๋‹ค. 

 

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

์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์—๋Š” ์‹คํŒจํ•œ ์—ฐ์‚ฐ ์ด๋ฆ„, ์‹คํŒจ ์œ ํ˜• ๋“ฑ์˜ ์ •๋ณด๋ฅผ ๋‹ด์•„ ์˜ˆ์™ธ์™€ ํ•จ๊ป˜ ๋˜์ง„๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋กœ๊น… ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด catch ๋ธ”๋ก์—์„œ ์˜ค๋ฅ˜๋ฅผ ๊ธฐ๋กํ•˜๋„๋ก ์ถฉ๋ถ„ํ•œ ์ •๋ณด๋ฅผ ๋„˜๊ฒจ์ค€๋‹ค. 

 

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

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

์™ธ๋ถ€ API๋ฅผ ๊ฐ์Œ€ ๋•Œ์˜ ์žฅ์ 

1) ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋กœ๊ทธ๋žจ ์‚ฌ์ด์—์„œ ์˜์กด์„ฑ์ด ํฌ๊ฒŒ ์ค„์–ด๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜์ค‘์— ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๊ฐˆ์•„ํƒ€๋„ ๋น„์šฉ์ด ์ ๋‹ค.

2) ๊ฐ์‹ธ๊ธฐ ํด๋ž˜์Šค์—์„œ ์™ธ๋ถ€ API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋„ฃ์–ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ๋„ ์‰ฌ์›Œ์ง„๋‹ค.

3) ํ”„๋กœ๊ทธ๋žจ์ด ์‚ฌ์šฉํ•˜๊ธฐ ํŽธํ•œ API๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํŠน์ • ์—…์ฒด๊ฐ€ API๋ฅผ ์„ค๊ณ„ํ•œ ๋ฐฉ์‹์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

ACMEPort port = new ACMEPort(12);

try {
    port.open();
} catch (DeviceResponseException e) {
    reportPortError(e);
    logger.log("Device response exception", e);
} catch (๋˜ ๋‹ค๋ฅธ exception) { ... } {
} catch (๋˜ ๋‹ค๋ฅธ exception) { ... )

 

ACMEPort port = new ACMEPort(12);

try {
    port.open();
} catch (PortDeviceFailure e) {
    reportPortError(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 (๋˜ ๋‹ค๋ฅธ ์—๋Ÿฌ e) {
        	throw new PortDeviceFailure(e);
        }
    }
}

 

์ •์ƒ ํ๋ฆ„์„ ์ •์˜ํ•˜๋ผ

ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๊ฐ์ฒด๋ฅผ ์กฐ์ž‘ํ•ด ํŠน์ˆ˜ ์‚ฌ๋ก€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” Special Case Pattern์„ ์ด์šฉํ•˜๋ฉด ํด๋ž˜์Šค๋‚˜ ๊ฐ์ฒด๊ฐ€ ์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ์„ ์บก์Šํ™”ํ•ด์„œ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ๊ฐ€ ์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค.

 

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

๋ฉ”์„œ๋“œ์—์„œ null์„ ๋ฐ˜ํ™˜ํ•˜๊ณ ํ”ˆ ์œ ํ˜น์ด ๋“ ๋‹ค๋ฉด ๊ทธ ๋Œ€์‹  ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ฑฐ๋‚˜ ํŠน์ˆ˜ ์‚ฌ๋ก€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์‚ฌ์šฉํ•˜๋ ค๋Š” ์™ธ๋ถ€ API๊ฐ€ null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋ฉด ๊ฐ์‹ธ๊ธฐ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ฑฐ๋‚˜ ํŠน์ˆ˜ ์‚ฌ๋ก€ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹์„ ๊ณ ๋ คํ•œ๋‹ค.

Collections.emptyList()๋ฅผ ์ž˜ ํ™œ์šฉํ•ด๋ณด์ž

 

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

์ธ์ˆ˜๋กœ null์ด ๋„˜์–ด์˜ค๋ฉด ์ฝ”๋“œ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๋ง์ด๋‹ค. 

1) ์˜ˆ์™ธ ์œ ํ˜•์„ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜

2) assert๋ฌธ์„ ์‚ฌ์šฉ

์ด ๋‘ ๋ฐฉ๋ฒ•์€ ๋ฌธ์ œ๋ฅผ ์™„์ „ํžˆ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์›์ธ ํ•จ์ˆ˜๋ฅผ ์ž˜ ํŒŒ์•…ํ•ด๋ณด์ž. 

 

์˜ค๋Š˜ ์ฝ์€ ์†Œ๊ฐ

NullPointException์„ ์ž์ฃผ ๋ฐœ์ƒ์‹œ์ผฐ๋Š”๋ฐ, ์•„์˜ˆ null๊ฐ’์ด ๋Œ์•„์˜ค์ง€ ์•Š๋„๋ก ๊ฐœ๋ฐœํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด ๋†€๋ผ์› ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ null ๊ด€๋ จ ์—๋Ÿฌ๊ฐ€ ๋œฐ ๊ฒฝ์šฐ IDE์—์„œ assert๋ฌธ์„ ์‚ฝ์ž…ํ•˜๋ผ๋Š” ํŒ์—…์ฐฝ์ด ๋– ์„œ ์ข…์ข… ๋„ฃ๊ณค ํ–ˆ๋Š”๋ฐ, ๊ทธ๋ƒฅ IDE ์˜ค๋ฅ˜๋งŒ ์‚ฌ๋ผ์งˆ ๋ฟ null ์—๋Ÿฌ๋ฅผ ์™„์ „ํžˆ ๋ง‰์ง€๋Š” ๋ชปํ•ด์„œ ์–ด๋ฆฌ๋‘ฅ์ ˆํ–ˆ๋˜ ๊ธฐ์–ต์ด ์žˆ๋‹ค. ์˜ค๋Š˜์—์„œ์•ผ ๊ฒจ์šฐ assert๋ฌธ์„ ๊ฒ€์ƒ‰ํ•ด๋ดค๋Š”๋ฐ ๊ฐ€๊ธ‰์  ์‚ฌ์šฉํ•˜์ง€ ๋ง๋ผ๋Š” ๋ง์ด ์žˆ์–ด์„œ ๋†€๋ž๋‹ค. ์ง€๊ธˆ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง ์ค‘์ธ๋ฐ ๊ณ ์ณ์•ผ ํ•  ๊ฒŒ ๋Š˜์–ด์„œ ๊ธฐ์˜๋‹ค^^

์•ž์œผ๋กœ๋Š” null ์ฒ˜๋ฆฌ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•  ์ง€ ๊ณ ๋ฏผํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์›์ธ ์ฝ”๋“œ๋ฅผ ์ž˜ ํƒ๊ตฌํ•ด์„œ ์–ด๋–ป๊ฒŒ๋“  ๊ฐ์ฒด๋‚˜ ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด์•ผ๊ฒ ๋‹ค.

 

๊ถ๊ธˆํ•˜๊ฑฐ๋‚˜ ์ž˜ ์ดํ•ด๋˜์ง€ ์•Š๋Š” ๋‚ด์šฉ

ํ™•์ธ๋œ ์˜ˆ์™ธ(checked exception)

RuntimeException์„ ์ƒ์†ํ•˜์ง€ ์•Š๊ณ  ๊ผญ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” exception

๋ฏธํ™•์ธ ์˜ˆ์™ธ(unchecked exception)

๋ช…์‹œ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋˜๋Š” exception

https://devlog-wjdrbs96.tistory.com/351

 

[Java] Checked Exception vs Unchecked Exception ์ •๋ฆฌ

์ฒดํฌ ์˜ˆ์™ธ์™€ ์–ธ์ฒดํฌ ์˜ˆ์™ธ(Checked, Unchecked Exception) ์ž๋ฐ”์˜ ์˜ˆ์™ธ๋Š” ํฌ๊ฒŒ 3๊ฐ€์ง€๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒดํฌ ์˜ˆ์™ธ(Checked Exception) ์—๋Ÿฌ(Error) ์–ธ์ฒดํฌ ์˜ˆ์™ธ(Unchecked Exception) ์ž๋ฐ”์—์„œ ์—๋Ÿฌ , ์˜ˆ์™ธ ๊ด€๋ จ..

devlog-wjdrbs96.tistory.com

 

assert

์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๋ฐ˜๋“œ์‹œ ์–ด๋–ค ๊ฐ’์ผ์ง€ ํ™•์‹ ํ•˜๋Š” ๊ฐ’, ๋ฒ”์œ„ ๋˜๋Š” ํ™•์‹คํ•œ ํด๋ž˜์Šค์˜ ์ƒํƒœ ๋“ฑ์„ ์ฒดํฌํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์˜ ์‹ ๋ขฐ์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด์„œ ์‚ฌ์šฉ๋œ๋‹ค. ํ•˜์ง€๋งŒ ๋˜๋„๋ก์ด๋ฉด ์‚ฌ์šฉ์„ ์ž์ œํ•˜์ž

"you have to think about ... assert is turned off" If you need to do that, you are doing it wrong. "asserts are a premature optimization of limited use"

https://offbyone.tistory.com/294

 

Java์—์„œ assert ์‚ฌ์šฉํ•˜๊ธฐ

Java์—์„œ ๋‹จ์–ธ๋ฌธ assert๋Š” JDK 1.4 ๋ถ€ํ„ฐ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๊ณ  ์˜ˆ์•ฝ์–ด ์ž…๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋ฒ•์€ ๋‘ ๊ฐ€์ง€ ํ˜•์‹์ด ์žˆ๋Š”๋ฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. assert expression1; assert expression1: expression2; ์ฒซ ๋ฒˆ์งธ๋Š” ์ธ์ž๋กœ..

offbyone.tistory.com

https://stackoverflow.com/questions/2758224/what-does-the-java-assert-keyword-do-and-when-should-it-be-used

 

What does the Java assert keyword do, and when should it be used?

What are some real life examples to understand the key role of assertions?

stackoverflow.com

 

ํŠน์ˆ˜ ์‚ฌ๋ก€ ํŒจํ„ด

ํŠน์ˆ˜ ์‚ฌ๋ก€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” non-null ๊ฐ์ฒด๋‚˜ ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

https://java-design-patterns.com/patterns/special-case/

 

Special Case

 View Source on Github Special Case Extensibility Behavioral IntentDefine some special cases, and encapsulates them into subclasses that provide different special behaviors.ExplanationReal world exampleIn an e-commerce system, presentation layer expects a

java-design-patterns.com

 

๋Œ“๊ธ€