...

์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น - ISP (Interface Segregation Principle)
ISP ์์น์ด๋ ๋ฒ์ฉ์ ์ธ ์ธํฐํ์ด์ค ๋ณด๋ค๋ ํด๋ผ์ด์ธํธ(์ฌ์ฉ์)๊ฐ ์ค์ ๋ก ์ฌ์ฉํ๋ Interface๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค๋ ์๋ฏธ๋ก, ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉ์ ๋ง๊ฒ ๋ ๊ฐ๊ธฐ ๋ถ๋ฆฌํด์ผํ๋ค๋ ์ค๊ณ ์์น์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
๋ง์ฝ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋๋ค์ ๋ฒ์ฉ์ ์ผ๋ก ์ด๊ฒ์ ๊ฒ ๊ตฌํํ๋ค๋ฉด, ๊ทธ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ํด๋์ค๋ ์์ ์ด ์ฌ์ฉํ์ง ์๋ ์ธํฐํ์ด์ค๋ง์ ์ต์ง๋ก ๊ตฌํ ํด์ผ ํ๋ ์ํฉ์ด ์ฌ ์๋ ์๋ค.
๋ํ ์ฌ์ฉํ์ง๋ ์๋ ์ธํฐํ์ด์ค์ ์ถ์ ๋ฉ์๋๊ฐ ๋ณ๊ฒฝ๋๋ค๋ฉด ํด๋์ค์์๋ ์์ ์ด ํ์ํ๊ฒ ๋๋ค.
์ฆ, ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น์ด๋ ์ธํฐํ์ด์ค๋ฅผ ์๊ฒ ๋ถ๋ฆฌํจ์ผ๋ก์จ, ํด๋ผ์ด์ธํธ์ ๋ชฉ์ ๊ณผ ์ฉ๋์ ์ ํฉํ ์ธํฐํ์ด์ค ๋ง์ ์ ๊ณตํ๋ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด Pet ์ธํฐํ์ด์ค๋ฅผ ์ข๋ ์๊ฒ ๋๋์ผ๋ก์จ ๊ฐ ์ ์๋๋ฌผ ํด๋์ค์ ์ญํ ๊ณผ ๋ง๊ฒ ์์ ์์ผ์ค์ผ๋ก์, ํด๋์ค์ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ํ์ ํ ์ ์๋ค๋ ์ด์ ์ ์ป์ ์ ์์ผ๋ฉฐ ์ ์ฐํ๊ฒ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ํ์ฅํ๊ฑฐ๋ ์์ ํ ์ ์๊ฒ ๋๋ค.

์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น์ ๋ง์น ๋จ์ผ ์ฑ ์ ์์น๊ณผ ๋น์ทํ๊ฒ ๋ณด์ด๋๋ฐ, SRP ์์น์ด ํด๋์ค์ ๋จ์ผ ์ฑ ์์ ๊ฐ์กฐํ๋ค๋ฉด, ISP๋ ์ธํฐํ์ด์ค์ ๋จ์ผ ์ฑ ์์ ๊ฐ์กฐํ๋ค๊ณ ๋งํ ์ ์๋ค.
๋ค๋ง ์ ์ํ ์ ์ ์ธํฐํ์ด์ค๋ ํด๋์ค์ ๋ค๋ฅด๊ฒ ์ถ์ํ์ด๊ธฐ ๋๋ฌธ์ ์ฌ๋ฌ๊ฐ์ ์ญํ ์ ๊ฐ์ง๋๋ฐ ์์ด ์ ์ฝ์ด ์๊ธด ํ๋ค.
์ฆ, SRP ์์น์ ๋ชฉํ๋ ํด๋์ค ๋ถ๋ฆฌ๋ฅผ ํตํ์ฌ ์ด๋ฃจ์ด์ง๋ค๋ฉด, ISP ์์น์ ์ธํฐํ์ด์ค ๋ถ๋ฆฌ๋ฅผ ํตํ์ฌ ์ด๋ฃจ์ด ์ง๋ค๊ณ ๋ณผ ์ ์๋ค.
๋ํ SRP ์์น์ ํด๋์ค ์ฑ ์์ ๋ฒ์์ ๋ํด ๋ถ๋ฆฌ ๊ธฐ์ค์ด ๋ค๋ฅด๋ฏ์ด, ์ธํฐํ์ด์ค๋ฅผ ๋ถ๋ฆฌํ๋ ๊ธฐ์ค์ ์ํฉ์ ๋ฐ๋ผ ๋ค๋ฅด๋ค.
ํต์ฌ์ ๊ด๋ จ ์๋ ๊ธฐ๋ฅ๋ผ๋ฆฌ ํ๋์ ์ธํฐํ์ด์ค์ ๋ชจ์ผ๋ ์ง๋์น๊ฒ ์ปค์ง์ง ์๋๋ก ํฌ๊ธฐ๋ฅผ ์ ํํ๋ผ๋ ์ ์ด๋ค.
ISP ์์น ์๋ฐ ์์ ์ ์์ ํ๊ธฐ
์ฐ๋ฆฌ๋ ์ค๋งํธํฐ ์ข ๋ฅ์ ํด๋์ค๋ฅผ ๊ตฌํํ๊ธฐ ์์ ์ธํฐํ์ด์ค๋ก ์ค๋งํธํฐ์ ์ถ์ํ ํ์๋ค.
์ค๋งํธํฐ ์ธํฐํ์ด์ค์๋ ์ค๋งํธํฐ์ด๋ผ๋ฉด ๊ฐ์ง๊ณ ์์ ํตํ๋ ๋ฉ์ธ์ง ๊ธฐ๋ฅ ์ด์ธ์๋ ๋ฌด์ ์ถฉ์ , AR ๋ทฐ์ด, ์์ฒด์ธ์ ๋ฑ์ ๋ค์ฑ๋ก์ด ๊ธฐ๋ฅ์ ํฌํจํ๊ณ ์๋ค.
interface ISmartPhone {
void call(String number); // ํตํ ๊ธฐ๋ฅ
void message(String number, String text); // ๋ฌธ์ ๋ฉ์ธ์ง ์ ์ก ๊ธฐ๋ฅ
void wirelessCharge(); // ๋ฌด์ ์ถฉ์ ๊ธฐ๋ฅ
void AR(); // ์ฆ๊ฐ ํ์ค(AR) ๊ธฐ๋ฅ
void biometrics(); // ์์ฒด ์ธ์ ๊ธฐ๋ฅ
}
๋ง์ผ ๊ฐค๋ญ์ S20์ด๋ S21 ํด๋์ค๋ฅผ ๊ตฌํํ๋ค๋ฉด, ์ต์ ์ค๋งํธํฐ ๊ธฐ์ข ์ธ ๋งํผ ๊ฐ์ฒด์ ๋์ ๋ชจ๋๊ฐ ํ์ํ๋ฏ๋ก ISP ์์น์ ๋ง์กฑํ๊ฒ ๋๋ค.
class S20 implements ISmartPhone {
public void call(String number) {
}
public void message(String number, String text) {
}
public void wirelessCharge() {
}
public void AR() {
}
public void biometrics() {
}
}
class S21 implements ISmartPhone {
public void call(String number) {
}
public void message(String number, String text) {
}
public void wirelessCharge() {
}
public void AR() {
}
public void biometrics() {
}
}
๊ทธ๋ฌ๋ ์ต์ ๊ธฐ์ข ์ค๋งํธํฐ ๋ฟ๋ง ์๋๋ผ ๊ตฌํ ๊ธฐ์ข ์ค๋งํธํฐ ํด๋์ค๋ ๋ค๋ค์ผ ํ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
๊ฐค๋ญ์ S3 ํด๋์ค๋ฅผ ๊ตฌํํด์ผ ํ๋ค๋ฉด ๋ฌด์ ์ถฉ์ , ์์ฒด์ธ์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ํฌํจ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ ๊ฒ ๋๋ค๋ฉด ์ถ์ ๋ฉ์๋ ๊ตฌํ ๊ท์น์ ์ค๋ฒ๋ผ์ด๋ฉ์ ํ๋, ๋ฉ์๋ ๋ด๋ถ๋ ๋น๊ณต๊ฐ์ผ๋ก ๋๊ฑฐ๋ ํน์ ์์ธ(Exception)์ ๋ฐ์ํ ๋ก ๊ตฌ์ฑํด์ผ ํ๋ค.
๊ฒฐ๊ตญ ํ์ํ์ง๋ ์์ ๊ธฐ๋ฅ์ ์ด์ฉ์์์ด ๊ตฌํํด์ผํ๋ ๋ญ๋น๊ฐ ๋ฐ์๋ ๊ฒ์ด๋ค.
class S3 implements ISmartPhone {
public void call(String number) {
}
public void message(String number, String text) {
}
public void wirelessCharge() {
System.out.println("์ง์ ํ์ง ์๋ ๊ธฐ๋ฅ ์
๋๋ค.");
}
public void AR() {
System.out.println("์ง์ ํ์ง ์๋ ๊ธฐ๋ฅ ์
๋๋ค.");
}
public void biometrics() {
System.out.println("์ง์ ํ์ง ์๋ ๊ธฐ๋ฅ ์
๋๋ค.");
}
}
๋ฐ๋ผ์ ๊ฐ๊ฐ์ ๊ธฐ๋ฅ์ ๋ง๊ฒ ์ธํฐํ์ด์ค๋ฅผ ์๊ฒ ๋ถ๋ฆฌํ๋๋ก ๊ตฌ์ฑํ๋ค.
๊ทธ๋ฆฌ๊ณ ์๊ฒ ๋ถ๋ฆฌ๋ ์ธํฐํ์ด์ค๋ฅผ ํด๋์ค๊ฐ ์ง์๋๋ ๊ธฐ๋ฅ๋ง์ ์ ๋ณํ์ฌ implements ํ๋ฉด ISP ์์น์ด ์ง์ผ์ง๊ฒ ๋๋ค.

interface IPhone {
void call(String number); // ํตํ ๊ธฐ๋ฅ
void message(String number, String text); // ๋ฌธ์ ๋ฉ์ธ์ง ์ ์ก ๊ธฐ๋ฅ
}
interface WirelessChargable {
void wirelessCharge(); // ๋ฌด์ ์ถฉ์ ๊ธฐ๋ฅ
}
interface ARable {
void AR(); // ์ฆ๊ฐ ํ์ค(AR) ๊ธฐ๋ฅ
}
interface Biometricsable {
void biometrics(); // ์์ฒด ์ธ์ ๊ธฐ๋ฅ
}
class S21 implements IPhone, WirelessChargable, ARable, Biometricsable {
public void call(String number) {
}
public void message(String number, String text) {
}
public void wirelessCharge() {
}
public void AR() {
}
public void biometrics() {
}
}
class S3 implements IPhone {
public void call(String number) {
}
public void message(String number, String text) {
}
}
ISP ์์น ์ ์ฉ ์ฃผ์์
SRP ์ ISP ์์น ์ฌ์ด์ ๊ด๊ณ
์์์ SRP๊ฐ ํด๋์ค์ ๋จ์ผ ์ฑ ์ ์์น์ด๋ผ๋ฉด, ISP๋ ์ธํฐํ์ด์ค์ ๋จ์ผ ์ฑ ์ ์์น์ด๋ผ๊ณ ํ๋ค.
์ฆ, ์ธํฐํ์ด์ค์ ๊ธฐ๋ฅ์ ๋ํ ์ฑ ์์ ๋ง๊ฒ ์ถ์ ๋ฉ์๋๋ฅผ ๊ตฌ์ฑํ๋ฉด ๋๋ค๋ ๋ง์ด๋ค.
ํ์ง๋ง ์ฑ ์์ ์ค์ํ๋๋ผ๋ ์ค๋ฌด์์๋ ISP๊ฐ ๋ง์กฑ๋์ง ์์ ์ ์๋ ์ผ์ด์ค๊ฐ ์กด์ฌํ๋ค.

์๋ฅผ๋ค์ด ์์ ๊ฐ์ด ๊ฒ์ํ ์ธํฐํ์ด์ค์ ๊ธ์ฐ๊ธฐ, ์ฝ๊ธฐ, ์ญ์ ์ถ์ ๋ฉ์๋๊ฐ ์ ์๋์ด ์๋ค. ์ด๋ค์ ๋ชจ๋ ๊ฒ์ํ์ ํ์ํ ๊ธฐ๋ฅ๋ค์ด๋ฉฐ ๊ฒ์ํ๋ง์ ์ด์ฉํ๋ ๋จ์ผ ์ฑ ์์ ์๋ฐฐ๋์ง ์๋๋ค.
ํ์ง๋ง ์ด๋ฅผ ๊ตฌํํ๋ ์ผ๋ฐ ์ฌ์ฉ์ ์ ์ฅ์์ ๊ฒ์๊ธ ๊ฐ์ ์ญ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ ISP ์๋ฐ์ผ๋ก ์ด์ด์ง๋ค.
๋ฐ๋ผ์ ์ฑ ์์ ์ ๊ตฌ์ฑํด ๋์ ๊ฒ ๊ฐ์ง๋ง ์ค์ ์ ์ฉ๋๋ ๊ฐ์ฒด์๊ฒ ๋ถํฉ๋์ง ์์ ์ ์๊ธฐ ๋๋ฌธ์ ์ฑ ์์ ๋ ๋ถ๋ฆฌํด์ผ ํ๋ค.
์ ๋ฆฌํ์๋ฉด, ISP๋ SRP๋ฅผ ๋ง์กฑํ๋ฉด ์ฑ๋ฆฝ๋๋๊ฐ ๋ผ๊ณ ์ง๋ฌธํ๋ค๋ฉด ๋ฐ๋์ ๊ทธ๋ ๋ค๊ณ ๋ ๋ณผ ์ ์๋ค๊ณ ๋ต๋ณํ๋๊ฒ ๋ง์์ง๋ ๋ชจ๋ฅธ๋ค.
์ธํฐํ์ด์ค ๋ถ๋ฆฌ๋ ํ๋ฒ๋ง
ISP ์์น์ ์ฃผ์ํด์ผ ํ ์ ์ ํ๋ฒ ์ธํฐํ์ด์ค๋ฅผ ๋ถ๋ฆฌํ์ฌ ๊ตฌ์ฑํด๋๊ณ ๋์ค์ ๋ฌด์ธ๊ฐ ์์ ์ฌํญ์ด ์๊ฒจ์ ๋ ์ธํฐํ์ด์ค๋ค์ ๋ถ๋ฆฌํ๋ ํ์๋ฅผ ๊ฐํ์ง ๋ง๋ผ๋ ์ ์ด๋ค.
์ด๋ฏธ ๊ตฌํ๋์ด ์๋ ํ๋ก์ ํธ์ ๋ ์ธํฐํ์ด์ค๋ค์ ๋ถ๋ฆฌํ๋ค๋ฉด, ์ด๋ฏธ ํด๋น ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ ์๋ ์จ๊ฐ ํด๋์ค๋ค๊ณผ ์ด๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ํด๋ผ์ด์ธํธ(์ฌ์ฉ์)์์ ๋ฌธ์ ๊ฐ ์ผ์ด๋ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ณธ๋ ์ธํฐํ์ด์ค๋ผ๋ ๊ฑด ํ๋ฒ ๊ตฌ์ฑํ์์ผ๋ฉด ์ ๋งํด์ ๋ณํ๋ฉด ์๋๋ ์ ์ฑ ๊ฐ์ ๊ฐ๋ ์ด๋ค.
๋ฐ๋ผ์ ์ฒ์ ์ค๊ณ๋ถํฐ ๊ธฐ๋ฅ์ ๋ณํ๋ฅผ ์๊ฐํด๋๊ณ ์ธํฐํ์ด์ค๋ฅผ ์ค๊ณํด์ผ ํ๋๋ฐ, ์ด๋ ํ์ค์ ์ผ๋ก ์ฐธ ํ๋ ๋ถ๋ถ์ด๋ฉฐ ์ญ์ ๊ฐ๋ฐ์์ ์ญ๋์ ๋ฌ๋ ธ๋ค.
# ์ฐธ๊ณ ์๋ฃ
https://www.nextree.co.kr/p6960/
https://youtu.be/GGHfgSD2udw
https://youtu.be/WBJm4U86m5k
https://www.oreilly.com/library/view/architectural-patterns/9781787287495/d1eb4b7b-880e-48f8-b71b-405b6d4bdd41.xhtml
https://blog.itcode.dev/posts/2021/08/16/interface-segregation-principle
์ด ๊ธ์ด ์ข์ผ์ จ๋ค๋ฉด ๊ตฌ๋ & ์ข์์
์ฌ๋ฌ๋ถ์ ๊ตฌ๋
๊ณผ ์ข์์๋
์ ์์๊ฒ ํฐ ํ์ด ๋ฉ๋๋ค.