실 용 디자인 모델 의 상태 모델
5829 단어 구조 설계
1. 상태 모드 란 무엇 인가
상태 모드 (State Pattern) 는 디자인 모델 의 하나 로 행위 모델 에 속한다.그 정의 (Design Pattern 에서 유래) 는 대상 의 내 적 상태 가 바 뀌 었 을 때 행동 을 바 꿀 수 있 도록 하 는 것 으로 이 대상 은 종 류 를 바 꾼 것 처럼 보인다.
상태 모드 는 대상 상 태 를 제어 하 는 조건 식 이 너무 복잡 할 때의 상황 을 해결 합 니 다.상태의 판단 논 리 를 서로 다른 상 태 를 나타 내 는 일련의 유형 으로 옮 기 면 복잡 한 판단 논 리 를 간소화 할 수 있다.
상태 모드 의 주요 적용 장면 은:
4. 567917. 한 대상 의 행 위 는 그의 상태 에 달 려 있 고 운행 시간 에 상태 에 따라 그의 행 위 를 바 꿔 야 한다
4. 567917. 한 조작 에 방대 한 여러 가지 구 조 를 포함 하고 이런 가 지 는 대상 의 상태 에 결정 된다
2. 상태 모드 사용 의 전제 조건
정의 에서 볼 수 있 듯 이 상태 모델 의 목적 은 상태 와 서로 다른 상태 에서 의 행 위 를 격 리 시 켜 복잡 한 조건 판단 을 간소화 하기 위해 상태 모델 을 선택 할 지 여 부 를 결정 할 때 이 복잡 한 상태 변화 에 착안 해 야 한다.내 가 엔지니어 에 게 추천 하 는 첫 번 째 방법 은 바로 상태 도 를 그 리 는 것 이다.만약 이 상태 도 를 그 릴 수 있 고 어느 정도 복잡 도가 있다 면 상태 모드 를 선택 하 는 것 을 고려 할 수 있다. 그렇지 않 으 면 사용 을 중단 하지 않 는 다.모든 모델 에 적용 되 는 장면 이 있 고 성 가 비 를 이해 할 수 있 습 니 다.하나의 모델 을 사용 하면 원가 도 증가 하고 수익 도 가 져 올 수 있다.이것 은 진지 하 게 생각해 야 한다.2 - 3 가지 상태 만 있 는 경우 모델 을 사용 하면 최소 3 - 4 가지 유형 이 증가 하고 유형 간 결합 이 증가 하 며 일부 엔지니어 의 실현 단 계 는 코드 의 이해 성 을 현저히 낮 출 수 있 기 때문에 얻 는 것 보다 잃 는 것 이 많다.또는 이런 상 태 는 표지 역할 만 할 뿐 서로 다른 상태 에서 대상 의 행 위 를 바 꿀 필요 가 없다. 그러면 상태 모델 을 제사 지 낼 필요 가 없고 상수 나 매 거 로 문 제 를 해결 할 수 있다.
3. 상태 모드 사용
다음은 상태 모드 의 사용 을 설명 하 는 실례 가 필요 합 니 다.
만약 에 저희 가 간단 한 업무 설명 이 있다 고 가정 합 니 다. 특정한 소프트웨어 는 파일 업로드 와 다운로드 서 비 스 를 제공 할 수 있 습 니 다. 업로드 작업 이 든 다운로드 작업 이 든 사용자 의 시작 이나 취소 동작 에 응 할 수 있 습 니 다.사용자 가 파일 을 선택 한 후 시작 을 누 르 면 작업 을 시작 하고 네트워크 전송 을 할 수 있 습 니 다. 이 과정 에서 사용 자 는 취 소 를 누 르 면 작업 을 중단 할 수 있 습 니 다. 취 소 된 작업 은 초기 상태 로 복원 하여 사용자 가 다시 시작 할 때 까지 기다 릴 수 있 습 니 다.
상태 모드 를 선택 한 후에 다음 단계 의 디자인 작업 을 진행 할 수 있 습 니 다.다음 과 같은 사고방식 으로 진행 할 것 을 건의 합 니 다.
3.1. 상태 도 작성
업무 설명 에 따라 상태 도 를 작성 하 는 것 은 다음 그림 과 같다.
3.2 디자인 도표
상태 도 에 따라 다음 과 같은 유형 도 를 설계 하 다.
이 유 도 는 책 속 의 상태 모델 의 도표 와 일치 합 니 다. 지금까지 우 리 는 교과서 의 디자인 에 따라 분류 와 직책 을 구분 해 왔 습 니 다. 예 를 들 어 Task 류 의 start () 방법 은 State 의 start () 방법 에 간단하게 의뢰 한 것 입 니 다.
public void start(){
currentState.start();
}
3.3 처리 상태 이전
다음은 상태 도 에서 의 상 태 를 옮 겨 실현 하 는 것 이다.PendingState 코드 를 예 로 들 면
public classPendingState extends State {
public PendingState(Task task){
super(task);
}
@Override
public void start() {
task.changeCurrentState(task.getRunningState());
}
@Override
public void cancel() {
//Do nothing
}
}
Pending 상태 에서 start 를 실행 하면 task 의 현재 상 태 를 Running 상태 로 변경 하고 cancel 작업 을 수행 하면 아무것도 하지 않 습 니 다.다른 상태의 변천 은 이런 식 으로 유추 된다.
3.4 구체 적 인 동작 실현
지금 우리 가 해 야 할 일 은 바로 진정한 기능 을 실현 하 는 것 이다. 이 예 에서 바로 인터넷 전송 동작 이다.이 일 을 할 때 우 리 는 교과서 의 예 에 따 르 면 이런 구체 적 인 집행 은 State 에서 이 루어 져 야 하지만 실제 상황 에서 Task 에 넣 어 이 루어 질 수 있 을 까?
3.4.1. State 에서 동작 을 수행 합 니 다.
만약 에 실현 을 State 에 두 면 모든 구체 적 인 State 는 현재 의 상태, 지난번 의 상태 등 복잡 하고 실수 하기 쉬 운 논 리 를 판단 하지 않 고 현재 상태 에서 의 실현 만 확보 하면 된다.그러나 이 사례 의 모든 상태 에서 사용자 가 두 가지 작업 을 수행 할 수 있 도록 해 주 는 상황 에 있어 서 우리 가 처리 해 야 할 일 은 상대 적 으로 복잡 합 니 다. 적어도 cancel 에 서 는 running 에서 시작 하 는 http request 를 가 져 와 네트워크 요청 을 취소 하 는 작업 을 수행 해 야 합 니 다.이것 은 같은 작업 대상 (httpRequest) 이 서로 다른 State 클래스 에서 전달 하 는 문제 입 니 다.
이 를 통 해 Task 류 는 업로드 다운로드 에 필요 한 인 자 를 가지 고 있 습 니 다. 예 를 들 어 요청 유형, 자원 경로 등 은 State 하위 클래스 에서 얻 을 수 있 습 니 다.그리고 실제 상황 에서 작업 상태, 진도 등 정 보 를 다른 방식 으로 상부 논리 나 UI 에 보고 해 야 한다. Observer 모드 를 통 해 이 루어 진다 고 가정 하면 Subject 는 Task 를 선택 하기 때문에 구체 적 인 상황 을 파악 하 는 State 는 이런 문 제 를 동시에 신경 써 야 한다.
3.4.2. Task 가 동작 을 수행 합 니 다.
위의 분석 을 보면 구체 적 인 동작 을 Task 에서 실현 하 는 것 이 비교적 편리 하 다. 매개 변 수 는 Task 에 있 고 HttpRequest 도 Task 에 있 으 며 대외 적 인 Listener 유지 와 리 셋 도 Task 에 있어 Client 의 이해 와 사용 에 유리 하고 유지 하기 쉽다.동시에 내부 집적 성 이 향상 되 었 다.
따라서 본 사례 는 교과서 와 달리 실제 상황 에 따라 디자인 조정 을 했 고 조정 후의 유 도 는 다음 과 같다.
PendingState 의 start () 방법의 코드 변경:
public void start() {
task.changeCurrentState(task.getRunningState());
task.performStart();
}
Task 의 하위 클래스 가 perfomrStart () 의 실현 을 책임 집 니 다.
3.5. 상태 이동
자세히 분석 하면 실제 상태 이전 은 두 가지 로 나 뉘 는데 하 나 는 외부 에서 촉발 하여 발생 하 는 상태 이전 이다. 즉, 앞에서 말 한 것 은 사용자 가 start, cancel 로 인해 발생 하 는 상태 이전 이다.다른 하 나 는 임 무 를 수행 하 는 과정 에서 내부 에서 발생 하 는 상태 이전 이다. 예 를 들 어 하나의 Running 상태의 임 무 를 순조롭게 수행 한 후에 상 태 를 Finished 로 변경 해 야 한다.이런 자연 이동 상태 에 대해 서 는 실현 할 때 어떻게 처리 하 는 것 이 더 편리 한 지 를 고려 해 야 한다.
우 리 는 당연히 상태 에 대한 이전 이 State 에 집중 되 어 분 리 된 State 류 를 충분히 이용 할 수 있 기 를 바란다.예 를 들 면:
public void start() {
task.changeCurrentState(task.getRunningState());
task.performStart();
task.changeCurrentState(task.getFinishedState());
}
그러나 이렇게 하 는 전 제 는 퍼 포 먼 스 스타트 () 가 동기 화 방법 이 어야 한 다 는 것 이다.비동기 라면 동작 이 끝나 기 전에 상 태 를 Finished 로 설정 하 는 것 이 잘못된 것 이 분명 합 니 다. 이러한 상황 에서 상태 변 화 는 permStart () 방법 으로 전환 하 는 것 이 편리 합 니 다.퍼 포 먼 스 스타트 () 방법 에서 이러한 내부 상태 이전 을 실현 하 는 것 이다.예 를 들 면:
void performStart() {
//...success
changeCurrentState(getFinishedState());
}
4. 소결
상태 모델 의 목적 성 이 매우 강하 고 식별 하고 사용 하기 쉽 지만 사용 할 때 자신의 사고방식 을 정리 하 는 데 주의해 야 한다. 특히 중요 한 것 은 실제 상황 에 따라 변통 하 는 것 이다.교과서 의 코드 예시, 도표 예 시 는 모두 이 디자인 방안 의 의 도 를 설명 하기 위 한 것 이지 표준적 인 템 플 릿 이 아니 라 그대로 옮 기 면 디자인 모델 의 본 뜻 을 잃 게 된다.모델 의 의 도 를 충분히 이해 하고 실제 에서 응용 하려 면 교과서 에서 튀 어 나 와 자신의 사고 로 디자인 모델 을 자신의 모델 로 바 꿀 수 있다.
- 전재 에 오신 것 을 환영 합 니 다. 출처 를 밝 혀 주세요.http://blog.csdn.net/caowenbin ——
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
NGINX 학습 노트 - 전달 요청 헤드기본적으로 NGINX 는 프 록 시 요청 시 HTTP 헤드 필드 두 개 를 'Host' 와 'Connection' 으로 다시 정의 하고 값 이 비어 있 는 헤드 필드 를 삭제 합 니 다.'Host' 는 $proxy_...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.