본문 바로가기

화면 설계와 피드백

입력·처리 중·성공·실패 상태를 나누고 결과 코드를 사용자 문구와 복구 행동으로 변환합니다.

사용자는 신청 버튼을 누르고 화면에서 아무 변화도 보이지 않으면 한 번 더 누를 수 있습니다. 저장은 되었는데 성공 문구가 없으면 실패했다고 생각하고, 실패 뒤 입력이 지워지면 같은 정보를 다시 작성해야 합니다. 화면 설계는 예쁜 배치뿐 아니라 사용자가 현재 상태와 다음 행동을 알게 하는 일입니다.

이 단원은 앞에서 정한 신청 결과 코드를 사용자 언어로 바꾸고, 입력·처리 중·완료·실패 상태를 설계합니다. 실행 예제는 메시지 모델을 명령줄에서 확인합니다. 실제 브라우저 화면을 완성하는 실습은 아니며, DOM·CSS를 배우지 않은 독자도 상태와 피드백을 이해할 수 있도록 범위를 좁힙니다.

무엇을 보고 결정해야 하는가

사용자 인터페이스(UI)는 사람이 시스템에 입력하고 응답을 받는 접점입니다. 명령줄도 UI이고 폼·버튼·화면도 UI입니다. 사용성(usability)은 주어진 사용자가 주어진 목표를 얼마나 수월하게 이루는지와 관련이 있습니다. 사용자가 누구이며 무엇을 해야 하는지 없이 색상만 평가하면 이 목적을 놓칩니다.

독서 모임 신청 화면에는 모임 제목·일시·모집 상태·남은 자리·신청 행동이 필요합니다. 남은 자리 계산에 사용할 전체 참가자 ID 목록까지 사용자에게 보여 줄 필요는 없습니다. 필요한 결정 정보와 내부 데이터는 구분합니다. 참가자 수에서 남은 자리를 계산하고 실제 요청 시 다시 규칙을 검사합니다.

화면 영역사용자의 질문넣을 정보
모임 요약어디에 신청하는가제목·일시·정원
모집 정보지금 신청 가능한가열림/종료·남은 자리
입력무엇을 제공해야 하는가회원 ID 이름표·필요한 형식
처리 결과신청되었는가성공/거절 이유·다음 행동
내 참가 내역나중에도 확인 가능한가신청한 모임과 취소 방법

입력에 필요한 조건은 placeholder만으로 알려 주지 않습니다. 입력을 시작하면 placeholder가 사라져 기준을 잊기 쉽습니다. 이름표와 짧은 설명을 입력 옆에 유지합니다. 이 실습의 회원 ID 입력은 인증을 구현한 화면이 아니라 이미 받은 ID를 테스트하는 장치입니다.

입력 상태와 업무 상태를 섞지 않는다

화면은 EDITING, SENDING, SUCCEEDED, FAILED 같은 표현 상태를 가질 수 있습니다. 이 값은 모임의 OPEN/CLOSED와 다릅니다. SENDING은 요청을 보낸 뒤 응답을 기다린다는 뜻이고, 모임이 모집을 종료했다는 뜻이 아닙니다.

요청 상태에 따라 안내와 다음 행동을 바꾼다

입력을 유지하며 신청을 준비한다. 거절 또는 장애를 확인한 뒤 가능한 다음 행동을 알린다. 각 단계의 값과 전환 이유를 비교합니다.

SOFTWARE ENGINEERING · CH3-3

요청 상태에 따라 안내와 다음 행동을 바꾼다

전송만 끝난 상태와 저장이 완료된 상태를 구별합니다.

요청 상태에 따라 안내와 다음 행동을 바꾼다입력 중에서 요청 대기로 이동하고 저장 성공은 완료 안내, 거절 또는 장애는 입력을 보존하는 복구 안내로 분기합니다.신청 요청저장 성공거절·장애입력 중EDITING응답을 기다림SENDING완료 안내SUCCEEDED복구 안내FAILED실패한 입력은 보존한다

입력 중에서 요청 대기로 이동하고 저장 성공은 완료 안내, 거절 또는 장애는 입력을 보존하는 복구 안내로 분기합니다.

이 예의 조건

  • 본문과 전체 도표의 예를 따라 입력 중부터 실패 안내까지 진행합니다.
예의 값과 변화
관찰·상황값·보충 정보변화·이유
입력 중

입력을 유지하며 신청을 준비한다.

  • 요청·화면 1: EDITING
  • 요청·화면 2: 입력 보유
    응답 대기

    전송 완료는 저장 성공이 아니다.

    • 요청·화면 1: SENDING
    • 요청·화면 2: 중복 클릭 억제
    • 저장 결과 대기
    실패 안내

    거절 또는 장애를 확인한 뒤 가능한 다음 행동을 알린다.

    • 요청·화면 1: FAILED
    • 요청·화면 2: 입력 보존
    • 요청·화면 3: FULL이면 다른 모임 확인
    • 저장 성공이면 SUCCEEDED라는 별도 분기 유지

    요청 상태에 따라 안내와 다음 행동을 바꾼다

    입력을 유지하며 신청을 준비한다. 거절 또는 장애를 확인한 뒤 가능한 다음 행동을 알린다. 각 단계의 값과 전환 이유를 비교합니다.

    SOFTWARE ENGINEERING · CH3-3

    요청 상태에 따라 안내와 다음 행동을 바꾼다

    전송만 끝난 상태와 저장이 완료된 상태를 구별합니다.

    요청 상태에 따라 안내와 다음 행동을 바꾼다입력 중에서 요청 대기로 이동하고 저장 성공은 완료 안내, 거절 또는 장애는 입력을 보존하는 복구 안내로 분기합니다.신청 요청저장 성공거절·장애입력 중EDITING응답을 기다림SENDING완료 안내SUCCEEDED복구 안내FAILED실패한 입력은 보존한다

    입력 중에서 요청 대기로 이동하고 저장 성공은 완료 안내, 거절 또는 장애는 입력을 보존하는 복구 안내로 분기합니다.

    이 예의 조건

    • 본문과 전체 도표의 예를 따라 입력 중부터 실패 안내까지 진행합니다.
    예의 값과 변화
    관찰·상황값·보충 정보변화·이유
    입력 중

    입력을 유지하며 신청을 준비한다.

    • 요청·화면 1: EDITING
    • 요청·화면 2: 입력 보유
      응답 대기

      전송 완료는 저장 성공이 아니다.

      • 요청·화면 1: SENDING
      • 요청·화면 2: 중복 클릭 억제
      • 저장 결과 대기
      실패 안내

      거절 또는 장애를 확인한 뒤 가능한 다음 행동을 알린다.

      • 요청·화면 1: FAILED
      • 요청·화면 2: 입력 보존
      • 요청·화면 3: FULL이면 다른 모임 확인
      • 저장 성공이면 SUCCEEDED라는 별도 분기 유지

      처리 중에는 신청 행동을 잠시 비활성화하고 ‘신청을 처리하고 있습니다’라고 알릴 수 있습니다. 이는 같은 화면에서 실수로 반복 클릭하는 것을 줄일 뿐 모든 중복 요청을 막는 장치는 아닙니다. 성공은 실제 저장 성공을 확인한 뒤 알립니다. 요청 전송만 끝났는데 ‘신청 완료’로 표시하면 저장 실패를 성공으로 오해하게 됩니다.

      실패하면 오류와 안내를 구별합니다. 빈 ID는 사용자가 고칠 수 있는 입력 오류입니다. 정원 마감은 입력이 잘못된 것이 아니라 업무 상황입니다. 모집 종료도 ‘잘못된 회원’이라고 표시하지 않습니다. 정확한 원인과 가능한 다음 행동을 짝지어야 불필요한 재시도가 줄어듭니다.

      결과 코드와 문구를 분리한다

      FULL 같은 코드는 프로그램이 분기할 안정적인 값이고 문구는 사람이 이해할 표현입니다. 함수의 정책 판단마다 한국어 문장을 직접 넣으면 문구 수정이 업무 규칙 수정과 섞입니다. 표현 모델(view model)은 결과를 화면에서 쓸 정보로 바꾸어 둔 값입니다.

      아래 예제는 정책을 다시 계산하지 않고 받은 결과 코드만 표현으로 바꿉니다. 모르는 코드가 들어오면 성공처럼 넘기지 않고 오류를 드러내어 코드와 화면 계약의 불일치를 찾게 합니다. 반환하는 tone은 색상을 직접 정한 것이 아니라 표현 의도를 가리킵니다.

      저장소 최상위 폴더에서 다음 명령을 실행합니다. Node.js가 설치되어 있어야 하며 패키지를 추가로 설치하지 않습니다. 두 번째 인수를 생략하면 이 장의 예제를 모두 실행합니다.

      node dev-note/scripts/software-engineering-lab/examples/ch3.mjs ch3-3
      ch3-3 실행 예제
      function presentResult(result) {
        const messages = {
          INVALID_MEMBER: "회원 ID는 소문자로 시작하는 1~24자이며 소문자·숫자·하이픈만 사용할 수 있습니다.",
          CLOSED: "모집이 종료되었습니다. 다른 모임을 확인해 주세요.",
          ALREADY_REGISTERED: "이미 신청한 모임입니다. 참가 내역을 확인해 주세요.",
          FULL: "남은 자리가 없습니다. 다른 모임을 확인해 주세요.",
          REGISTERED: "신청이 완료되었습니다. 참가 내역에서 확인할 수 있습니다.",
        };
        if (!Object.hasOwn(messages, result.code)) {
          throw new Error("Unknown result code: " + result.code);
        }
        return {
          text: messages[result.code],
          tone: result.ok ? "success" : "notice",
          keepInput: !result.ok,
        };
      }
      
      const successView = presentResult({ ok: true, code: "REGISTERED" });
      const fullView = presentResult({ ok: false, code: "FULL" });
      console.log(successView.text);
      console.log(fullView.text);
      console.log("실패 뒤 입력 유지:", fullView.keepInput);

      첫 두 줄에서 성공 문구와 정원 마감 안내를 읽고, 마지막 true로 실패 뒤 입력을 보존하는 선택을 확인합니다. ‘정원 마감’에서는 같은 입력으로 다시 누르라고 안내하지 않습니다. 결과 코드가 같은데 문구가 서로 다른 이유를 말한다면 표현 함수의 문제를 의심할 수 있습니다.

      keepInput은 이 화면 설계의 규칙입니다. 이름과 ID가 잘못되었을 때에도 사용자가 고칠 부분만 수정하게 합니다. 성공 뒤 폼을 비울지 그대로 둘지는 화면 목표에 따라 달라질 수 있습니다. 여기서는 성공 후 참가 내역을 보여 주는 다음 단계로 간다는 가정입니다.

      접근성과 복구 동작을 같이 검토한다

      빨간색 테두리만으로 실패를 설명하면 색을 구별하기 어려운 사용자는 이유를 알 수 없습니다. 오류는 텍스트로 쓰고 어떤 입력과 연결되는지 표시합니다. 키보드만으로 입력·신청·취소를 진행할 수 있어야 하며 초점 위치를 알아볼 수 있어야 합니다.

      브라우저 구현에서는 입력의 label, 설명/오류 연결, 응답 후 동적으로 바뀌는 상태의 알림을 고려합니다. W3C WAI의 폼 알림 안내는 오류 원인과 해결 방법, 성공 확인, 입력 가까이의 피드백을 다룹니다. 문구 모델 테스트만 통과했다고 화면 접근성까지 검증했다고 말할 수는 없습니다.

      연결이 끊긴 경우도 주의합니다. 서버가 저장한 뒤 응답만 끊겼다면 사용자는 성공 여부를 모를 수 있습니다. 이때 ‘실패했으니 다시 신청’이라고 단정하는 것보다 참가 내역 확인 방법이 필요합니다. 이 교재의 현재 로컬 예제는 네트워크를 사용하지 않으므로 이 시나리오는 요구와 설계로 기록하며 뒤의 변경·저장 논의에 연결합니다.

      작은 사용성 관찰

      화면 초안은 종이에 그려도 됩니다. ‘열린 모임에 신청하고 참가 내역에서 확인해 보세요’라는 작업을 주고, 안내하지 않은 상태에서 사용자가 어디서 멈추는지 관찰합니다. 완료 여부·잘못 누른 행동·모르는 용어를 기록합니다. ‘디자인이 마음에 드나요’라는 질문만으로 목표 수행을 확인하기는 어렵습니다.

      정해진 수의 사용자만 참여하면 어떤 테스트든 충분하다는 규칙은 없습니다. 새 정보가 계속 나오거나 특정 사용자 집단을 다루지 못했다면 범위를 확장합니다. 테스트 목적과 사용자 특성에 따라 관찰 대상을 정하고 관찰한 범위만 보고합니다.

      독립 문제: 저장 실패를 고칠 수 있는 폼

      도서 추천 폼은 제목과 추천 이유를 받습니다. 빈 제목은 입력 오류이고, 금지된 책은 정책 거절이며, 디스크 쓰기 실패는 저장 장애입니다. 성공하면 추천 목록으로 이동합니다. 실패 뒤 이미 쓴 추천 이유를 보존해야 합니다.

      네 결과의 문구·입력 유지 여부·다음 행동을 표로 만들고, 저장 장애를 만났을 때 ‘추천 완료’ 문구가 나오는 잘못된 흐름을 찾아 고칩니다. 결과 코드와 한국어 문구를 한 함수에 섞지 않는 구조도 제안합니다.

      힌트

      사용자가 입력을 수정해서 해결할 수 있는 실패와 다시 시도하거나 상태를 확인해야 하는 장애는 다릅니다. 네 가지 모두에 같은 ‘입력 오류’ 제목을 붙이지 않습니다.

      풀이

      빈 제목에는 제목 입력 위치와 작성 요청, 정책 거절에는 금지 기준과 다른 책 선택, 저장 장애에는 저장을 완료하지 못했다는 사실과 입력 보존·재시도 안내, 성공에는 완료 사실과 목록 확인을 보여 줍니다. 실패 세 종류는 추천 이유를 유지하고 성공만 다음 화면으로 이동합니다.

      완료 문구는 저장 함수 호출 직후가 아니라 저장 성공 응답을 받은 분기에서 생성합니다. 업무/저장 코드가 결과를 반환하고 표현 함수가 문구와 화면 행동을 정하면 문구를 바꾸어도 금지 도서 판정에 영향을 주지 않습니다. 목록 이동은 성공을 확인한 뒤 실행하며 오류는 색상 외 텍스트로 알립니다.

      앞뒤 개념을 묶는다

      유스케이스는 사용자의 목표, 상태 모델은 허용 조건, 화면 설계는 그 판단을 사용자가 알아볼 표현을 제공합니다. 다음 장은 이 세 책임이 한 함수에 얽히지 않도록 모듈을 나누고, 변경이 어디에 영향을 주는지 살펴봅니다.


      원자료와 더 읽기

      장원사이버평생교육원 「소프트웨어공학」 PDF 물리 186–200쪽의 주제를 바탕으로 설명·도표·실습을 새로 구성했습니다.

      폼 구현은 W3C WAI 폼 알림 안내를 참고합니다. 원자료의 UI 가이드 중 인원 수·입력 취소 등을 모든 화면의 고정 규칙으로 적용하지 않고 작업 목표에 맞게 검토합니다.

      Object.hasOwn은 안내표 자체의 키만 확인합니다. in은 상속한 toString 같은 이름도 포함하므로 알려진 결과 코드 검사에 사용하지 않습니다. 예제는 이런 이름도 오류로 거절하는지 확인합니다.