SOLID ์์น์ด๋?
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์์ด ๋ฐ๋์ ์์์ผ ํ๋ SOLID ์์น์ ์๊ธฐ ์์ ํด๋์ค ๋ด๋ถ์ ์์ง๋๋ ๋์ด๊ณ , ํ ํด๋์ค์์ ๊ฒฐํฉ๋๋ ๋ฎ์ถ๋ ๊ฒ์ ์ด์ ์ ๋๋ค. ์ด๋ ํด๋์ค์๊ฒ ๋ ๋ฆฝ๋ ์ญํ ์ ๋ถ์ฌํ๊ธฐ ์ํจ์ด๋ฉฐ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ด ๋์ ์ํํธ์จ์ด๋ฅผ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๐ฒ SRP(Single Responsibility Principle) : ๋จ์ผ ์ฑ ์ ์์น
- ํด๋์ค๊ฐ ๋ณ๊ฒฝ๋๋ ์ด์ ๊ฐ ๋จ ํ ๊ฐ์ง์ฌ์ผ ํ๋ค
๐ฒ OCP(Open Close Principle) : ๊ฐ๋ฐฉ/ํ์ ์์น
- ํ์ฅ์๋ ์ด๋ ค์๊ณ , ์์ ์ ๋ํด์๋ ๋ซํ์์ด์ผ ํ๋ค.
๐ฒ LSP(Liskov Substitution Principle) : ๋ฆฌ์ค์ฝํ ์นํ ์์น
- ํ์ ํ์ ์ ์์ ํ์ ์ผ๋ก ๋์ฒดํ ์ ์์ด์ผ ํ๋ค
๐ฒ ISP(Interface Segregation Priciple) : ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น
- ํด๋ผ์ด์ธํธ์ ๋ชฉ์ ๊ณผ ์ฉ๋์ ์ ํฉํ ์ธํฐํ์ด์ค๋ง์ ์ ๊ณตํ๋ ๊ฒ
๐ฒ DIP(Dependency Inversion Principle) : ์์กด ์ญ์ ์์น
- ๊ณ ์ฐจ์ ๋ชจ๋์ ์ ์ฐจ์ ๋ชจ๋์ ๊ตฌํ์ ์์กดํด์๋ ์๋๋ฉฐ, ์ ์์ค ๋ชจ๋์ด ๊ณ ์์ค ๋ชจ๋์ ์์กดํด์ผ ํ๋ค
๋จ์ผ ์ฑ ์ ์์น(SRP)
SRP๋ "ํด๋์ค๊ฐ ๋ณ๊ฒฝ๋๋ ์ด์ ๊ฐ ๋จ ํ ๊ฐ์ง์ฌ์ผ ํ๋ค"๊ณ ๋งํ๋ค. ์ฌ๊ธฐ์ ๋ณ๊ฒฝ์ ์ด์ ๋, ๋ชจ๋์ด ์ฌ๋ฌ ๋์์ด๋ ์กํฐ์ ๋ํด ์ฑ ์์ ์ง๋์ง ์๊ณ , ์ค์ง ํ๋์ ์กํฐ์ ์ํด์๋ง ์ฑ ์์ ์ ธ์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
์๋ฅผ ๋ค์ด, ์ฌ์ฉ์์ ์ ๋ ฅ ์ ๋ณด๋ฅผ ๋ฐ๊ณ ์ ์ฅํ๋ ๋น์ฆ๋์ค ๋ก์ง์ UserService์์ ์์ฑํ๋ค๊ณ ํด๋ณด์. ์ด๋์ ์กํฐ๋ ๋ค์ํ ์ ์ค์ผ์ด์ค๋ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์๋ค.
- ๊ธฐํ ์ธก์์์ ์๊ตฌ : ์ฌ์ฉ์๋ฅผ ์ถ๊ฐํ ๋ ์ญํ ์ ๋ํ ์ ์๊ฐ ํ์ํ๋ค.
- ๋ณด์ ์ธก์์์ ์๊ตฌ : ๋น๋ฐ๋ฒํธ ์ํธํ ๋ฐฉ์์ ๊ฐ์ ์ด ํ์ํ๋ค.
- ...
UserService์์ ์ด๋ฌํ ๋ก์ง์ ํด๋์ค ํ์ผ ํ๋์ ์ ๋ถ ์์ฑํ๋ค๋ฉด, ๋จ์ผ ์ฑ ์์ ์ง๋์ง ๋ชปํ๋ ๊ฒ์ด๋ค. ์ฆ, ์ฑ ์์ ๋ถ๋ด์ด ํ์ํ๋ค. ๊ฐ๋ น Encoder ํด๋์ค๋ฅผ ๋ง๋๋ ์์ผ๋ก ๋น๋ฐ๋ฒํธ ์ํธํ ๋ฐฉ์์ ๋ํ ๋ก์ง์ ๋ถ๋ฆฌํด์ผ ํ๋ค.
๋ฌผ๋ก , SRP๊ฐ ๋ช ํํ์ง ์์ ๊ฒฝ์ฐ๋ ์๋ค. ์ด๋ ์ ์ค์ผ์ด์ค๋ ์๊ตฌ ์ฌํญ์ ๋ฐ๋ผ ๋ง์ถ์ด ์ง๋ ๊ฒ์ด๋ฉฐ ์ ์ ํ ํ๋จ์ด ํ์ํ ๊ฒ์ด๋ค.
๊ฐ๋ฐฉ ํ์ ์์น(OCP)
OCP๋ "ํ์ฅ์๋ ์ด๋ ค์๊ณ , ์์ ์ ๋ํด์๋ ๋ซํ์์ด์ผ ํ๋ค."๋ผ๋ ์์น์ด๋ค. ์ด๋ ํ์ฅ์ ์ด๋ ค ์๋ค๋ ๊ฒ์ ์๊ตฌ์ฌํญ์ด ๋ณํ์ ๋ ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฝ๊ฒ ๊ธฐ๋ฅ ํ์ฅ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด๊ณ , ์์ ์ ๋ซํ์๋ค๋ ๊ฒ์ ๊ธฐ์กด์ ์ฝ๋๋ฅผ ์์ ํ์ง ์๊ณ ์ ํ๋ฆฌ์ผ์ด์ ๋์์ ๋ณ๊ฒฝํ ์ ์๋ค๋ ๋ง์ด๋ค.
์์ ์ ๋ซํ์๋ค๋ ๋ง์ด ์กฐ๊ธ ๋ชจํธํ๋ค. ํ์ง๋ง ์ด๋ ์์ ๋์๊ณผ ๋ฌด๊ดํ ๊ฒ์ ์์ ํ์ง ์๋ ๊ฒ์ ๋งํ๋ค. ์์ ๋ณด์๋, UserService์์ ๋น๋ฐ๋ฒํธ ์ํธํ์ ๊ด๋ จ๋ ํด๋์ค์ ์์ ์ด ํ์ํ๋ค๊ณ ํด๋ณด์. ์ด๋, ์ํธํ ๋ฐฉ์ ์์ฒด๋ฅผ ๋ฐ๊พธ์ด ๋ฒ๋ฆฌ๋ฉด ํด๋์ค๊ฐ ํต์ผ๋ก ๋ฐ๋๊ธฐ ๋๋ฌธ์ ์ํธ์์ ์ ํ ๋ฌด๊ดํ UserService ์ฝ๋ ๋ด์์๋ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ค.
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final SHA256PasswordEncoder passwordEncoder;
...
}
์ด๋ฌํ ์ผ์ด ๋ฐ์ํ๋ ์์ธ์ SHA256PasswordEncoder์ ๊ฐ์ด ๊ตฌ์ฒดํ๋ ํด๋์ค์ ์์กดํ์๊ธฐ ๋๋ฌธ์ด๋ค. OCP๋ฅผ ์งํค๊ธฐ ์ํด์๋ ์ด๋ ๊ฒ ๊ตฌ์ฒดํ๋ ํด๋์ค์ ์์กดํ๋ ๊ฒ์ด ์๋๋ผ "์ถ์ํ๋ ํด๋์ค"์ ์์กดํ์ฌ์ผ ํ๋ค.
์ฆ, UserService์์๋ ์ถ์ํ๋ ์ธํฐํ์ด์ค์ ์์กดํ์ฌ ๋น๋ฐ๋ฒํธ ์ํธํ ๋ฐฉ์์ด ๋ฐ๋์ด๋ UserService ๋ด์ ์ฝ๋๊ฐ ๋ฐ๋์ผ์ด ์๋๋ก ํ ์ ์๋ค.
public interface PasswordEncoder {
String encryptPassword(final String pw);
}
@Component
public class SHA256PasswordEncoder implements PasswordEncoder {
@Override
public String encryptPassword(final String pw) {
...
}
}
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public void addUser(final String email, final String pw) {
final String encryptedPassword = passwordEncoder.encryptPassword(pw);
final User user = User.builder()
.email(email)
.pw(encryptedPassword).build();
userRepository.save(user);
}
}
๊ทธ๋ ๋ค๋ฉด ๋ฌด์์ ์ถ์ํ์ ์์กดํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ผ๊น? ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ท๋ชจ์ ๋ฐ๋ผ ๊ณผ๋ํ ์ค๊ณ๊ฐ ๋ ์๋ ์๊ณ , ์ ์ ํ ์ ํ์ด ๋ ์๋ ์๋ค. ๊ฒฐ๊ตญ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ ๋ํ ๋น์ฉ์ด๊ธฐ์ ์๊ตฌ์ฌํญ๊ณผ ํ์ฅ ๊ฐ๋ฅ์ฑ์ ์ ๋ฐ์ ธ๋ณด์์ผ ํ๋ค.
๋ฆฌ์ค์ฝํ ์นํ ๋ฒ์น(LSP)
LSP๋ ํ์ ํ์ ์ ์์ ํ์ ์ผ๋ก ๋์ฒดํ ์ ์์ด์ผ ํ๋ค๋ ์์น์ด๋ค. ๋ค์๋งํด Upcasting ๋ ๊ฐ์ฒด ์ฐธ์กฐ ๋ณ์๊ฐ ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ทธ ์ญํ ์ ํ๋๋ฐ ๋ฌธ์ ๊ฐ ์์ด์ผ ํ๋ค. LSP๋ ์ธํฐํ์ด์ค์ ํด๋์ค ๊ด๊ณ, ๊ทธ๋ฆฌ๊ณ ์์ ํด๋์ค์ ํ์ํด๋์ค๊ฐ์ ๊ด๊ณ๋ฅผ ์ผ๋ง๋ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ ๊ตฌ์ฑํ๋๊ฐ ํต์ฌ ๊ด๊ฑด์ด๋ค.
์ด๋ฌํ ์ค๊ณ๋ฅผ ์ ํ๊ธฐ ์ํด์๋ ๊ณ์ธต์ด ์๋๋ผ ๋ถ๋ฅ๋ก์จ ํด๋์ค ๊ตฌ์ฑ์ ํด์ผํ๋ค. ์๋ฅผ ๋ค์ด, ์๋ฒ์ง์ ์๋ค์ ๊ด๊ณ๋ฅผ ์์๊ด๊ณ๋ก ๋ํ๋ธ๋ค๋ฉด ์๋ชป๋ ๊ฒ์ด๋ค. ์ด๋ ๊ณ์ธต์ ํด๋น๋๋ ๊ฒ์ด๋ฉฐ ์๋ค์ด ์๋ฒ์ง์ ํ ์ข ๋ฅ๋ผ๊ณ ๋งํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋น์ฐํ๊ฒ๋ ์๋ค์ด ์๋ฒ์ง์ ์ญํ ์ ํ๋ ๊ฒ์ ๋ ผ๋ฆฌ ์ ๋ง์ง ์๋ค.
๋ฐ๋ฉด, ๊ณค์ถฉ๊ณผ ์ฌ์ด๋ฒ๋ ์ ๊ฐ์ด ๋ถ๋ฅ๋ก์จ ํด๋์ค ๊ตฌ์ฑ์ ํ๋ ๊ฒ์ ์ฌ๋ฐ๋ฅธ ํํ์ด๋ค. ํ์ ํด๋์ค์ธ ์ฌ์ด๋ฒ๋ ๋ ์์ ํด๋์ค์ธ ๊ณค์ถฉ์ ์ญํ ์ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ฆ, ๋ฆฌ์ค์ฝํ ์นํ ์์น์ ํ์ ํด๋์ค๊ฐ ์์ ํด๋์ค์ ์ญํ ์ ๋์ ์ํํ ์ ์๋ ๊ฒ์ ๋งํ๋ฉฐ ๋ถ๋ฅ๋ก์จ, ํด๋์ค ๊ตฌ์ฑ์ ์ด๋ฃจ์ด์ผ ํ๋ค.
์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น(ISP)
ISP๋ "ํด๋ผ์ด์ธํธ์ ๋ชฉ์ ๊ณผ ์ฉ๋์ ์ ํฉํ ์ธํฐํ์ด์ค๋ง์ ์ ๊ณตํ๋ ๊ฒ" ์ด๋ค. ์ฆ, ์ํฉ๊ณผ ๊ด๋ จ์๋ ๋ฉ์๋๋ง์ ์ ๊ณตํ๋ผ๋ ๋ป์ธ๋ฐ ์ด๋ SRP(๋จ์ผ ์ฑ ์ ์์น)๊ณผ ๊ฐ์ ์์ธ์ ๋ํด ๋ค๋ฅธ ํด๊ฒฐ์ฑ ์ ์ ์ํ๋ ๊ฒ์ด๋ค.
์ด์ ์ ๋ณด์๋ SRP์ ์์ธ์ ๋๋ฌด ๋ง์ ์ฑ ์์ ์ฃผ์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ์๋ค. ๊ทธ๋์ ํ๋์ ์กํฐ์ ๋ํด์ ํ๋์ ์ฑ ์์ ์ง๋๋๋ก ํ์๋ค. ๋ฐ๋ฉด, ISP๋ ํด๋น ํด๋์ค๋ฅผ ์ชผ๊ฐ์ง ์๊ณ , ๊ทธ๋๋ก ๋๋ ๋์ ์ ์ธํฐํ์ด์ค ์ต์์ฃผ์ ์์น์ ์ํด ์ํฉ์ ๋ง๋ ๋ฉ์๋ ๋ง์ ์ ๊ณตํ๋๋ก ํํฐ๋งํ๋ค.
์ฆ, ์ํ๋ ์กํฐ์ ๋ฉ์๋๋ฅผ ํฌํจํ ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ๊ณ ์ด๋ฅผ ์์๋ฐ๋ ๊ตฌ์กฐ๋ก ๋ง๋ค์ด ํด๋ผ์ด์ธํธ์ ๋ชฉ์ ์ ๋ง๋๋ก ์ฌ์ฉํ ์ ์๋ค.
public class Person implements Developable, Cookable, Eatable {
@Override
public void develope() {
System.out.println("๊ฐ๋ฐํ๋ค.");
}
@Override
public void cook() {
System.out.println("์๋ฆฌํ๋ค.");
}
@Override
public void Eatable() {
System.out.println("๋ฐฅ ๋จน๋๋ค.");
}
}
์์กด ์ญ์ ์์น(DIP)
๋ง์ง๋ง์ผ๋ก DIP๋ ๊ณ ์ฐจ์ ๋ชจ๋์ ์ ์ฐจ์ ๋ชจ๋์ ๊ตฌํ์ ์์กดํด์๋ ์๋๋ฉฐ, ์ ์์ค ๋ชจ๋์ด ๊ณ ์์ค ๋ชจ๋์ ์์กดํด์ผ ํ๋ค๋ ๊ฒ์ ๋งํ๋ค.
์ด๋ ๊ณ ์ฐจ์ ๋ชจ๋์ ์ /์ถ๋ ฅ๊ณผ ๋จผ(๋น์ฆ๋์ค์ ์ฐ๊ด๋) ์ถ์ํ๋ ๋ชจ๋์ ์๋ฏธํ๊ณ , ์ ์์ค ๋ชจ๋์ ์ /์ถ๋ ฅ๊ณผ ๊ฐ๊น์ด(HTTP, ๋ฐ์ดํฐ๋ฒ ์ด์ค, ์บ์ ๋ฑ) ๊ตฌํ ๋ชจ๋์ ๋งํ๋ค.
์ฆ, ์ /์ถ๋ ฅ๊ณผ ๊ฐ๊น์ด ๊ตฌํ ํด๋์ค๊ฐ ๋น์ฆ๋์ค์ ์ฐ๊ด๋ ์ถ์ํ ํด๋์ค์ ์์กดํด์ผ ํ๋ค๋ผ๊ณ ํด์ํ ์ ์๋ค. ์ด์ ์ ๋ณด์๋, UserService๋ฅผ ํ ๋ฒ ์๊ฐํด๋ณด์. UserService์๋ ๋น๋ฐ๋ฒํธ ์ํธํ ๋ฐฉ์์ ๋ํด SRP๋ฅผ ์ ์ฉํ์ฌ ํด๋์ค ๋ถ๋ฆฌ๋ฅผ ์ด๋ฃจ๊ฒ ํด์ฃผ์๋ค.
์ด๋, ๊ตฌํ ๋ชจ๋์ธ ๊ฐ๊ฐ์ ์ํธํ ๋ฐฉ์(SHA256, Simple, BCrpt)์ ๋ํ ๊ฐ๊ฐ์ ํด๋์ค๋ฅผ ์๋น์ค ๋ก์ง์ ๋ฐ๋ผ ๊ฐ์ ๋ผ์ฐ๋ ๊ฒ์ ๊ฐ์ฒด ์งํฅ์ ์ด์ง ์๋ค. ์ฌ๊ธฐ์ ์์กด ์ญ์ ์์น์ ํตํด UserService๊ฐ ๊ฐ๊ฐ์ ์ํธํ ๋ฐฉ์์ธ ๊ตฌํ ๋ชจ๋์ ์์กดํ๋ ๊ฒ์ด ์๋๋ผ ๋น๋ฐ๋ฒํธ ์ํธํ ๋ฐฉ์ ์์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ์ธํฐํ์ด์ค์ ์์กดํ๋๋ก ํด์ผ ํ๋ค.
๋ค์๋งํด, _SHA256PasswordEncoder_ ํด๋์ค ๊ฐ์ ๊ตฌํ ๋ชจ๋์ ์์กดํ๋ ๊ฒ์ด ์๋, _PasswordEncoder_ ์ธํฐํ์ด์ค์ ์์กดํ๋ฉฐ ๊ฐ๊ฐ์ ์ํธํ ๊ตฌํ ๋ชจ๋์ด ์ด _PasswordEncoder_๋ฅผ ์์๋ฐ๋ ๊ทธ๋ฆผ์ด ๋์ด์ผ ํ๋ค.
References
'๐ซ Language > Java' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Java] ๋ชจ๋ ๊ฐ์ฒด๋ ๋ถ๋ณ ๊ฐ์ฒด์ฌ์ผ ํ ๊น? (0) | 2024.02.28 |
---|---|
[Java] ์ผ๊ธ ์ปฌ๋ ์ ๊ณผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ ์ ๋ํ์ฌ (2) | 2024.01.13 |
[Java] JUnit5 ์ฌ์ฉ๋ฒ ์์๋ณด๊ธฐ (0) | 2024.01.09 |
[Java] ๋ฉํฐ์ค๋ ๋์ ๋๊ธฐํ์ ๋ํด์ (1) | 2024.01.06 |
[Java] ๋๊ธฐ/๋น๋๊ธฐ & ๋ธ๋ญํน/๋ ผ๋ธ๋ญํน์ด๋? (0) | 2024.01.02 |