[Clean Code] 7์ฅ ์ค๋ฅ ์ฒ๋ฆฌ
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
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