C\#6 대 설계 원칙 에 대하 여 논 하 다.
이 여섯 가지 원칙 은 단일 직책 원칙,인터페이스 격 리 원칙,리 씨 교체 원칙,디 미트 법칙,후진 원칙,개폐 원칙 에 의존 하 는 것 이다.
단일 직책 원칙
단일 직책 원칙(SRP:Single responsibility principle)은 한 가지 유형 중 한 가지 원인 만 이 유형의 변 화 를 일 으 켜 야 한다 고 규정 한다.
단일 직책 원칙 의 핵심 은 결합 을 해제 하고 내부 집적 성 을 강화 하 는 것 이다.
질문:
//
public class DatabaseContext { }
public class Test
{
private readonly DatabaseContext _context;
public Test(DatabaseContext context)
{
_context = context;
}
//
public void UserLogin() { }
//
public void UserLogout() { }
//
public void AddUser() { }
//
public void UpdateUser() { }
//
public void DeleteUser() { }
}
Test 는 직책 P1(사용자 로그 인 및 탈퇴)과 P2(사용자 계 정 관리)두 가지 직책 을 담당 하 며,직책 P1 의 수요 변화 로 유형 을 수정 해 야 할 경우 정상 적 인 직책 P2 의 기능 이 고장 날 수 있 습 니 다.위의 코드 에서 두 직책 이 결합 되 어 여러 가지 기능 을 맡 았 다.
한 가지 유형 중 한 가지 원인 만 이 유형의 변 화 를 일 으 켜 야 한다.또한 한 가지 유형 은 하나의 기능 만 책임 지고 유형 중의 코드 는 밀접 한 관 계 를 가 져 야 한다.
위의 예제 코드 는 매우 간단 해서 우 리 는 자 연 스 럽 게 하나의 종 류 를 두 부분 으로 나 눌 수 있다.
//
public class DatabaseContext { }
public class Test1
{
private readonly DatabaseContext _context;
public Test1(DatabaseContext context)
{
_context = context;
}
//
public void UserLogin() { }
//
public void UserLogout() { }
}
public class Test2
{
private readonly DatabaseContext _context;
public Test2(DatabaseContext context)
{
_context = context;
}
//
public void AddUser() { }
//
public void UpdateUser() { }
//
public void DeleteUser() { }
}
따라서 단일 직책 원칙 의 해결 방법 은 서로 다른 직책 을 서로 다른 유형 이나 모듈 에 밀봉 하 는 것 이다.인터페이스 격 리 원칙
인터페이스 격 리 원칙(ISP:Interface Segregation Principle)은 인 터 페 이 스 를 세분 화해 야 한다.클래스 의 계승 은 최소 입도 에 세 워 지고 클 라 이언 트 가 계승 하 는 인 터 페 이 스 를 확보 하 는 데 모든 방법 이 필요 하 다.
필 자 는 외국 의 일부 자 료 를 찾 아 보 았 는데 대부분 인터페이스 격 리 원칙 을 다음 과 같이 정의 했다.
“Clients should not be forced to depend upon interfaces that they do not use.”
고객 에 게 사용 하지 않 는 방법 에 의존 하도록 강요 해 서 는 안 된다 는 뜻 이다.
이 원칙 에 대한 해석 에 있어 서 이 글 은 매우 투철 하 다.
https://stackify.com/interface-segregation-principle/
비대 한 인 터 페 이 스 를 더 작고 구체 적 인 인터페이스 로 나 누 어 인터페이스 가 담당 하 는 기능 을 더욱 단일 하 게 해 야 한다.
목적:소프트웨어 를 여러 개의 독립 된 부분 으로 나 누 어 변경 해 야 할 부작용 과 빈 도 를 줄인다.
필 자 는 두 가지 측면 에서 논술 하고 싶다.
첫째,여러 종류의 동물 을 묘사 할 때 우 리 는 서로 다른 종류의 동물 을 분류 할 수 있다.하지만 아직 부족 합 니 다.예 를 들 어 조류 에서 우리 가 기억 하 는 새 의 특징 은 새 가 날 수 있 지만 펭귄 은 날 지 못 합 니 다~
그러면 혈액의 색깔,척추 유 무 등 종의 특징 을 세분 화해 야 한다.
둘째,우 리 는 아래 코드 를 통 해 표현 할 수 있다.
//
public interface IUserLogin
{
//
void Login();
//
void Logout();
}
//
public interface IUserInfo
{
//
void AddUser();
//
void UpdateUser();
//
void DeleteUser();
}
위의 두 개의 인 터 페 이 스 는 서로 다른 기능 을 실현 하고 서로 교차 되 지 않 으 며 완벽 하 다.다음은 IUserLogin 인 터 페 이 스 를 계승 한 두 개의 코드 를 살 펴 보 겠 습 니 다.
// ,
public class Test1 : IUserLogin
{
public void Login(){}
public void Logout(){}
}
public class Test2 : IUserLogin
{
public void Login()
{
//
}
public void Logout()
{
}
}
Test 1 에 대해 서 는 로그 인 과 로그아웃 두 상태 에 따라 서로 다른 조작 을 합 니 다.그러나 Test 2 에 대해 서 는 이 상태 에 로그 인하 기만 하면 됩 니 다.다른 상황 은 상관 없습니다.그렇다면
Logout()
그 에 게 는 전혀 소 용이 없다.이것 이 바로 인터페이스 오염 이다.위의 코드 는 인터페이스 격 리 원칙 을 위반 했다.
그러나 인터페이스 격 리 원칙 은 인 터 페 이 스 를 너무 많이 세분 화하 기 쉽다 는 단점 이 있다.한 항목 에 수천 개의 인터페이스 가 나타 나 면 유지 보수 의 재난 이 될 것 이다.
따라서 인터페이스 격 리 원칙 은 유연 하 게 사용 해 야 한다.Test 2 에 있어 서 한 가지 방법 을 더 계승 하 는 것 은 큰 문제 가 없 으 며 사용 하지 않 으 면 된다.ASP.NET Core 에는 이런 실현 이 많다.
public void Function()
{
throw new NotImplementedException();
}
제4 장 에서 작 가 는 인터페이스 격 리 원칙 에 대해 네 가지 요 구 를 정리 했다.1 인 터 페 이 스 는 되도록 작 게:비대 한(Fat)인터페이스 가 나타 나 지 않 습 니 다.
2 인 터 페 이 스 는 높 은 내부 집적:인터페이스,클래스,모듈 의 처리 능력 을 향상 시 켜 야 한다.
3 맞 춤 형 서비스:작은 입자 의 인 터 페 이 스 는 큰 인 터 페 이 스 를 구성 하고 새로운 기능 을 유연 하 게 맞 출 수 있다.
4 인터페이스의 디자인 에 한계 가 있다.인터페이스의 입도 가 합 리 적 인지 아 닌 지 를 평가 하 는 고정 적 인 기준 이 있 기 어렵다.
단일 직책 원칙 과 인터페이스 격 리 원칙 에 대한 관계 와 대비 도 있다.
단일 직책 원칙 은 서비스 제공 자의 측면 에서 볼 때 내부 적 이 고 단일 한 직책 의 기능 을 제공 하 는 것 이다.
인터페이스 격 리 원칙 은 사용자 의 측면 에서 볼 때 높 은 내부 집적 과 낮은 결합 을 실현 하 는 것 이다.
인터페이스 격 리 원칙 의 입 도 는 더욱 작 을 수 있 고 여러 인 터 페 이 스 를 통 해 단일 직책 원칙 에 부합 되 는 유형 을 유연 하 게 구성 할 수 있다.
우 리 는 단일 직책 원칙 은 유형 을 중심 으로 토론 하 는 것 을 보 았 다.인터페이스 격 리 원칙 은 인터페이스 에 대해 토론 하 는 것,즉 추상 에 대해 토론 하 는 것 이다.
개폐 원칙
개폐 원칙(Open/Closed Principle)규정:
"소프트웨어 의 대상(클래스,모듈,함수 등)은 확장 에 대해 개방 적 이 어야 하지만 수정 에 대해 서 는 폐쇄 적 입 니 다."
--'오 브 젝 트 지향 소프트웨어 건설'저자 버 트 랜 드 마 이 어
개폐 원칙 은 하나의 실체 가 소스 코드 를 바 꾸 지 않 는 전제 에서 행 위 를 변경 할 수 있 도록 하 는 것 을 의미한다.클래스 의 변경 은 원본 코드 를 수정 하 는 것 이 아니 라 코드 를 추가 하여 이 루어 집 니 다.
개폐 원칙 에는 메 야 개폐 원칙,다 태 개폐 원칙 이 있다.
메 야 개폐 원칙
코드 가 완성 되면 하나의 클래스 의 실현 은 오류 로 만 수정 되 어야 하 며,새로운 또는 변 경 된 특성 은 새로운 클래스 를 통 해 이 루어 져 야 합 니 다.
특징:상속,자 류 는 부 류 를 계승 하고 모든 방법 을 가 지 며 확대 한다.
다 중 개폐 원칙
이 원칙 은 부모 클래스 가 아 닌 인 터 페 이 스 를 사용 하여 서로 다른 실현 을 허용 합 니 다.코드 를 변경 하지 않 은 상태 에서 쉽게 교체 할 수 있 습 니 다.
현재 대부분의 경우 개폐 원칙 은 다 중 개폐 원칙 을 말한다.
다 중 개폐 원칙 에 대해 필 자 는 자 료 를 조회 한 결과 이 인 터 페 이 스 는 인터페이스 가 아니 라 추상 적 인 방법,가상 방법 을 말 하 는 것 을 발견 했다.
물음:대상 을 향 한 3 대 특성 은 무엇 입 니까?답:봉인,계승,다 태.
그래,다 중 개폐 원칙 은 바로 이 다 태 를 가리킨다.그러나 재 업로드(재 작성),숨 기기 에는 대응 하지 않 는 것 이 원칙 이다.
이것 은 예시 이다.
//
public class UserLogin
{
public void Login() { }
public void Logout() { }
public virtual void A() {/* */}
public virtual void B() {/* */ }
}
public class UserLogin1 : UserLogin
{
public void Login(string userName) { } // ?
public override void A() { } // √
public override void B() { } // √
public new void Logout() { } // ?
}
다 중 개폐 원칙 의 장점 은 추상 을 도입 하여 두 가지 소나무 결합 을 하 게 하고 코드 를 수정 하지 않 는 전제 에서 하위 클래스 로 부모 클래스(리 씨 교체 원칙)를 교체 할 수 있다 는 것 이다.인터페이스 와 추상 류 의 차이?
필 자 는 인 터 페 이 스 는 공 통 된 기준 을 실현 하기 위 한 것 이 라 고 어렴풋이 기억 했다.추상 은 코드 의 재 활용 을 위 한 것 이다.
물론 인터페이스 와 추상 은 리 씨 교 체 를 실현 할 수 있다.
개폐 원칙 을 통 해 우 리 는 다 형 을 알 수 있 고 인터페이스 와 추상 적 인 응용 장면 도 알 수 있다.
또 하나의 문 제 는 개폐 원칙 이 기능 을 수정 하거나 추가 할 때 기 존 코드 를 수정 하 는 것 이 아니 라 하위 클래스 를 통 해 이 루어 져 야 한 다 는 것 이다.부모 클래스 의 코드 를 다시 불 러 오고 숨 길 수 있 습 니까?
한편,개폐 원칙 의 핵심 은 구조 가 추상 적 이어서 자 류 파생 을 통 해 확 대 를 실현 하 는 것 이다.그런 얘 기 는 안 한 것 같은 데.
필 자 는 옳지 않다 고 생각한다...
먼저 아래 의 리 씨 교체 원칙 과 결합 하여 우 리 는 이 문 제 를 다시 토론 합 니까?
리 씨 교체 원칙
리 씨 교체 원칙(LSP:Liskov Substitution Principle)은 부 류 가 나타 나 는 곳 은 자 류 가 모두 나타 날 수 있다 고 요구 했다.
이것 은 자 류 가 반드시 부계 와 같은 행 위 를 해 야 한 다 는 것 을 요구한다.하위 클래스 가 모든 부모 클래스 의 인 스 턴 스 를 교체 할 수 있 을 때 만 리 씨 교체 원칙 에 부합 한다.
리 씨 교체 원칙 의 제약:
1 자 류 는 반드시 부류 의 추상 적 인 방법 을 실현 해 야 하지만 부류 에서 이미 실 현 된 방법 을 다시 써 서 는 안 된다.
2 하위 클래스 에 서 는 방법 을 증가 시 켜 기능 을 확장 할 수 있다.
3 하위 클래스 가 부모 클래스 를 덮어 쓰 거나 실현 하 는 방법(가상 방법/추상 적 방법)을 사용 할 때 방법의 입력 매개 변 수 는 제한 이 더욱 넓 고 반환 값 은 부모 클래스 방법 보다 더욱 엄격 하 다.
그래서 우 리 는 개폐 원칙 중의 예 를 보 았 다.자 류 는 부 류 를 다시 태 워 야 하 는 방법 이 아 닐 까?new 키 워드 를 사용 하여 부모 클래스 를 숨 기 는 방법 을 사용 해 야 합 니까?자 류 의 계승 을 확보 하기 위해 서 는 부 류 와 일치 하 는 특성 을 가지 고 있 으 므 로 이렇게 하 는 것 을 권장 하지 않 습 니 다.친.
개폐 원칙 을 실현 하 였 으 니 당연히 리 씨 교체 원칙 을 사용 할 수 있다.
후진 원칙 에 의존 하 다.
후진 원칙(Dependence Inversion Principle)에 의존 하려 면 프로그램 이 추상 적 인 인터페이스 에 의존 하고 구체 적 인 실현 에 의존 하지 말 아야 한다.
우 리 는 코드 에서 천천히 이론 을 발전 시 키 고 유도 할 수 있다.
//
public class UserLogin
{
public void Login(){}
public void Logout(){}
}
public class Test1 : UserLogin { }
public class Test2
{
private readonly UserLogin userLogin = new UserLogin();
}
public class Test3
{
private readonly UserLogin _userLogin;
public Test3(UserLogin userLogin)
{
_userLogin = userLogin;
}
}
위의 코드 에서 Test 1,Test 2,Test 3 는 모두 UserLogin 에 의존 합 니 다.위의 코드 에 무슨 문제 가 있 는 지 는 말 하지 않 고 거꾸로 하 는 원칙 에 따라 코드 를 이렇게 작성 해 야 합 니 다.
//
public interface IUserLogin
{
void Login(); //
void Logout(); //
}
//
public class UserLogin1 : IUserLogin
{
public void Login(){}
public void Logout(){}
}
//
public class UserLogin2 : IUserLogin
{
public void Login(){}
public void Logout(){}
}
public class Test4
{
private readonly IUserLogin _userLogin;
public Test4(IUserLogin userLogin)
{
_userLogin = userLogin;
}
}
후진 원칙 에 의존 하 는 것 은 추상 을 도입 하 는 데 있다.이런 추상 은 고급 모듈 과 바 텀 모듈 을 서로 분리 하 는 것 이다.고 층 모듈 과 바 텀 모듈 의 소나무 결합,바 텀 모듈 의 변동 은 고 층 모듈 이 필요 없 이도 변동 해 야 한다.의존 은 원칙 에 두 가지 사상 을 초래한다.
1 고 층 모듈 은 바 텀 모듈 에 의존 해 서 는 안 되 고 둘 다 추상 에 의존 해 야 한다.
2 추상 은 세부 사항 에 의존 해 서 는 안 되 고 세부 사항 은 추상 에 의존 해 야 한다.
추상 에 의존 하기 때문에 바 텀 모듈 은 추상 을 실현 하 는 모듈 을 임의로 교체 할 수 있다.
리 씨 교체 원칙 은 자 류 의 부 류 를 구 하 는 행위 가 일치 하고 자 류 는 부 류 를 교체 할 수 있다 는 것 이다.
후진 원칙 에 의존 하면 모든 방법의 행 위 는 완전히 다 를 수 있다.
디 미트 의 법칙
디 미트 법칙(Law of Demeter)은 두 가지 유형 간 에 가능 한 한 최소한 의 관 계 를 유지 하도록 요구한다.
예 를 들 어 대상 A 는 대상 B 를 직접 호출 하지 말고 중간 대상 C 를 통 해 통신 을 유지 해 야 한다.
참고 하 세 요.
장점:느슨 한 결합 으로 의존 도가 적 습 니 다.
단점:많은 포장 코드 를 작성 하여 복잡 한 읽 기 를 늘 리 고 모듈 간 의 통신 효율 이 낮 아 집 니 다.
필 자 는 많은 자 료 를 찾 았 는데 모두 자바 의...
일반적으로 디 미트 원칙,코드 의존 도치 원칙 과 리 씨 교체 원칙 등 은 디 미트 법칙 에 부합 한다 고 언급 하지 않 는 다.
이상 은 C\#6 대 디자인 원칙 에 대한 상세 한 내용 입 니 다.C\#6 대 디자인 원칙 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.