728x90
반응형

- 주제
>> 객체 지향 SOLID 원칙
(단일 책임 원칙 - S)
(개방 폐쇄 원칙 - O)
(리스코프 치환 원칙 - L)
(인터페이스 분리 원칙 - I)
(의존성 역전 원칙 - D)
>> 사용자인증시스템을 주제로 하는 예제
(나쁜 예)
(좋은 예)
*** SOLID원칙을 알고 있으면 다른 사람의 코드를 이해하는데 도움이 된다.
(추가적인 기능 구현 가능)
*** But, 많이 사용하면 그만큼 코드가 복잡해진다.
- 공부내용
1. SOLID 원칙(표)
원칙 | 개념 | 장점 | 단점 |
단일책임원칙 (SRP) |
각 클래스는 하나의 책임만 | 코드 이해, 유지보수 용이 |
클래스 수 증가 |
개방폐쇄원칙 (OCP) |
확장 가능, 수정 불가능 |
코드 재사용성, 확장 용이 |
초기설계가 복잡 |
리스코프치환원칙 (LSP) |
부모 클래스가 제공하는 모든 기능을 자식 클래스도 제대로 사용 |
코드 예측가능성 증가 | 잘못된 상속 관계로 인해 오류 발생 가능 |
인터페이스 분리원칙(ISP) |
필요한 기능만 포함된 작은 인터페이스를 여러 개 사용 |
유연성, 재사용성 증가 |
인터페이스 수 증가로 관리가 복잡 |
의존성역전원칙 (DIP) |
상위 모듈(클래스)이 하위 모듈(인터페이스)에 의존 |
유연성, 테스트용이성 증가 |
초기설정이 복잡 |
주제: 사용자 인증 시스템
2. 단일 책임 원칙
나쁜 예제
public class UserManager {
public void RegisterUser(string username, string password) {
// 사용자 등록 로직
// 비밀번호 해싱 로직
// 데이터베이스 저장 로직
}
public bool LoginUser(string username, string password) {
// 로그인 로직
// 데이터베이스 조회 로직
// 비밀번호 검증 로직
}
}
좋은 예제
public class UserManager {
private readonly IUserRepository _userRepository; // 사용자 저장소
private readonly IPasswordHasher _passwordHasher; // 비밀번호 해싱기
public UserManager(IUserRepository userRepository, IPasswordHasher passwordHasher) {
_userRepository = userRepository; // 의존성 주입
_passwordHasher = passwordHasher; // 의존성 주입
}
public void RegisterUser(string username, string password) {
var hashedPassword = _passwordHasher.HashPassword(password); // 비밀번호 해싱
_userRepository.SaveUser(username, hashedPassword); // 사용자 저장
}
public bool LoginUser(string username, string password) {
var user = _userRepository.GetUser(username); // 사용자 조회
return _passwordHasher.VerifyPassword(password, user.HashedPassword); // 비밀번호 검증
}
}
public interface IUserRepository {
void SaveUser(string username, string hashedPassword); // 사용자 저장
User GetUser(string username); // 사용자 조회
}
public interface IPasswordHasher {
string HashPassword(string password); // 비밀번호 해싱
bool VerifyPassword(string password, string hashedPassword); // 비밀번호 검증
}
3. 개방 폐쇄 원칙
나쁜 예제
public class UserManager {
public bool LoginUser(string username, string password) {
// 로그인 로직
// 기본 인증 방식
}
}
좋은 예제
public interface IAuthenticationService {
bool Authenticate(string username, string password); // 인증
}
public class UserManager {
private readonly IAuthenticationService _authService; // 인증 서비스
public UserManager(IAuthenticationService authService) {
_authService = authService; // 의존성 주입
}
public bool LoginUser(string username, string password) {
return _authService.Authenticate(username, password); // 인증
}
}
public class BasicAuthenticationService : IAuthenticationService {
public bool Authenticate(string username, string password) {
// 기본 인증 로직
}
}
public class OAuthAuthenticationService : IAuthenticationService {
public bool Authenticate(string username, string password) {
// OAuth 인증 로직
}
}
4. 리스코프 치환 원칙
나쁜 예제
public class User {
public virtual void Authenticate() {
// 일반 사용자 인증
}
}
public class GuestUser : User {
public override void Authenticate() {
throw new NotImplementedException("Guest users cannot authenticate"); // 예외
}
}
좋은 예제
public abstract class User {
public abstract void Authenticate(); // 인증
}
public class RegularUser : User {
public override void Authenticate() {
// 일반 사용자 인증
}
}
public class GuestUser : User {
public override void Authenticate() {
// 게스트 사용자 인증 (특별한 처리 없음)
}
}
5. 인터페이스 분리 원칙
나쁜 예제
public interface IUserService {
void Register(string username, string password); // 사용자 등록
bool Login(string username, string password); // 로그인
void SendPasswordResetEmail(string email); // 비밀번호 재설정 이메일 전송
}
public class UserService : IUserService {
public void Register(string username, string password) {
// 사용자 등록
}
public bool Login(string username, string password) {
// 로그인
}
public void SendPasswordResetEmail(string email) {
throw new NotImplementedException(); // 예외
}
}
좋은 예제
public interface IRegistrationService {
void Register(string username, string password); // 사용자 등록
}
public interface ILoginService {
bool Login(string username, string password); // 로그인
}
public interface IPasswordResetService {
void SendPasswordResetEmail(string email); // 비밀번호 재설정 이메일 전송
}
public class UserService : IRegistrationService, ILoginService {
public void Register(string username, string password) {
// 사용자 등록
}
public bool Login(string username, string password) {
// 로그인
}
}
6. 의존성 역전 원칙
나쁜 예제
public class UserManager {
private readonly SqlUserRepository _userRepository = new SqlUserRepository(); // 구체적 의존성
public void RegisterUser(string username, string password) {
_userRepository.SaveUser(username, password); // 사용자 저장
}
}
좋은 예제
public interface IUserRepository {
void SaveUser(string username, string password); // 사용자 저장
}
public class SqlUserRepository : IUserRepository {
public void SaveUser(string username, string password) {
// SQL 데이터베이스에 사용자 저장
}
}
public class UserManager {
private readonly IUserRepository _userRepository; // 추상화 의존성
public UserManager(IUserRepository userRepository) {
_userRepository = userRepository; // 의존성 주입
}
public void RegisterUser(string username, string password) {
_userRepository.SaveUser(username, password); // 사용자 저장
}
}
728x90
반응형
'🌐 유니티 (Unity)' 카테고리의 다른 글
Day 33 - 3D 게임(해와 달) (0) | 2024.05.28 |
---|---|
Day 32 - 동기와 비동기(Coroutine) (0) | 2024.05.27 |
Day 30 - Rigidbody ForceMode 와 Raycast (1) | 2024.05.24 |
Day 29 - 락 오브젝트(동기화작업 / 코루틴이나 잡시스템과 사용 가능) (1) | 2024.05.23 |
Day 28 - OnBecameInvisible 메서드(화면을 벗어난 총알 제거) (1) | 2024.05.17 |