맞춤 블록: 스타일 가이드

지난 몇 년간 Blockly Games팀과 Blockly Games팀은 새로운 블록을 개발하는 개발자에게 적용할 수 있는 많은 교훈을 얻었습니다. 다음은 Google에서 범한 실수 또는 다른 사람이 흔히 저지르는 실수입니다.

이는 Blockly의 시각적 스타일을 사용하여 배운 일반적인 교훈이며 일부 사용 사례나 디자인에는 적용되지 않을 수도 있습니다. 다른 솔루션도 있습니다. 또한 사용자에게 발생할 수 있는 문제와 이를 방지하는 방법이 모두 나와 있지는 않습니다. 모든 사례는 조금씩 다르며 고유한 장단점이 있습니다.

1. 조건문과 루프 비교

신규 사용자에게 가장 어려운 블록은 조건부와 루프입니다. 많은 블록 기반 환경에서는 이러한 두 블록을 모두 동일한 모양과 색상을 가진 동일한 '컨트롤' 카테고리로 그룹화합니다. 이로 인해 신규 사용자가 두 블록을 혼동하므로 종종 불편을 초래합니다. Blockly는 조건문과 루프를 각각 다른 색상으로 된 별도의 'Logic'과 'Loops' 카테고리로 이동하는 것을 권장합니다. 이렇게 하면 이러한 모양은 유사하지만 다르게 동작하는 고유한 아이디어라는 것을 명확하게 알 수 있습니다.

권장사항: 조건문과 루프를 별도로 유지하세요.

2. 단일 기반 목록

초보 프로그래머는 0 기반 목록을 처음 접할 때 나쁘게 반응합니다. 결과적으로 Blockly는 목록 및 문자열 색인 생성을 1 기반으로 만드는 방식으로 Lua와 Lambda Moo의 선두를 따릅니다.

Blockly를 더 많이 사용할 때는 텍스트로 더 쉽게 전환할 수 있도록 0 기반 목록이 지원됩니다. 나이가 어리거나 초보 연령대의 경우 여전히 1 기반 색인 생성이 권장됩니다.

권장: 첫 번째 수치는 1개입니다.

3. 사용자 입력

사용자로부터 매개변수를 가져오는 방법에는 세 가지가 있습니다. 드롭다운은 가장 제한적이며 간단한 튜토리얼과 연습에 적합합니다. 입력란이 있으면 더 자유롭게 창의성을 발휘할 수 있습니다. 일반적으로 섀도우 블록이 포함된 값 블록 입력은 정적 값이 아닌 값을 계산(예: 랜덤 생성기)할 수 있는 기회를 제공합니다.

권장사항: 사용자에게 적합한 입력 방법을 선택하세요.

4. 실시간 블록 이미지

블록 관련 문서에는 참조 중인 블록의 이미지가 포함되어야 합니다. 스크린샷을 찍는 방법은 간단합니다. 그러나 이러한 이미지가 50개 있고 애플리케이션이 50개 언어로 번역되면 갑자기 정적 이미지 중 하나가 2,500개의 정적 이미지를 유지하게 됩니다. 그런 다음 색 구성표가 변경되고 2,500개의 이미지를 다시 업데이트해야 합니다.

이 유지보수의 악몽에서 벗어나기 위해 Blockly Games는 모든 스크린샷을 읽기 전용 모드에서 Blockly로 실행 중인 인스턴스로 대체했습니다. 결과는 사진과 동일하게 보이지만 최신 상태입니다. 읽기 전용 모드 덕분에 국제화가 가능해졌습니다.

권장사항: 두 개 이상의 언어를 지원하는 경우 읽기 전용 모드를 사용하세요.

5. 또 다른 왼쪽

흥미롭게는 다른 국가의 아동은 아니지만 미국 아동의 피드백으로 좌파와 우파 사이의 만연한 혼란이 드러났습니다. 이 문제는 화살표를 추가하여 해결되었습니다. 방향이 아바타를 기준으로 상대적인 경우 화살표 스타일이 중요합니다. 아바타가 반대 방향을 바라보면 → 직선 화살표 또는 ↱ 회전 화살표가 혼란스러울 수 있습니다. 가장 유용합니다. ⟳ 원형 화살표는 돌린 각도가 화살표보다 작은 경우에도 마찬가지입니다.

권장사항: 가능한 경우 텍스트를 유니코드 아이콘으로 보완하세요.

6. 상위 수준 블록

가능하면 실행 성능이나 유연성을 저하하더라도 더 높은 수준의 접근 방식을 취해야 합니다. 다음과 같은 Apps Script 표현식을 살펴보세요.

SpreadsheetApp.getActiveSheet().getDataRange().getValues()

모든 잠재적 기능을 보존하는 1:1 매핑에서 위 표현식은 4개의 블록을 사용하여 작성됩니다. 하지만 Blockly는 더 높은 수준을 목표로 하며 전체 표현식을 캡슐화하는 하나의 블록을 제공합니다. 목표는 나머지 5% 는 더 어렵더라도 95% 사례에 맞게 최적화하는 것입니다. Blockly는 텍스트 기반 언어를 대체하기 위한 것이 아니며, 사용자가 텍스트 기반 언어를 사용할 수 있도록 초기 학습 과정부터 진행하도록 돕기 위한 것입니다.

권장사항: 맹목적으로 전체 API를 블록으로 변환하지 마세요.

7. 선택적 반환 값

텍스트 기반 프로그래밍의 많은 함수는 작업을 수행한 다음 값을 반환합니다. 이 반환 값은 사용되거나 사용되지 않을 수 있습니다. 스택의 pop() 함수를 예로 들 수 있습니다. 팝을 호출하여 마지막 요소를 가져와 삭제할 수도 있고, 반환 값이 무시되는 마지막 요소만 삭제하기 위해 팝을 호출할 수도 있습니다.

var last = stack.pop();  // Get and remove last element.
stack.pop();  // Just remove last element.

블록 기반 언어는 일반적으로 반환 값을 무시하는 데 적합하지 않습니다. 값 블록은 값을 허용하는 항목에 연결해야 합니다. 이 문제를 처리하는 몇 가지 전략이 있습니다.

a) 문제를 우회합니다. 대부분의 블록 기반 언어는 이러한 경우를 방지하기 위해 언어를 설계합니다. 예를 들어 Scratch에는 부작용과 반환 값이 모두 있는 블록이 없습니다.

b) 2개의 블록을 제공합니다. 도구 상자의 공간이 문제가 되지 않는다면 간단한 해결책은 이러한 유형의 블록을 각각 두 개씩 제공하는 것입니다. 하나는 반환 값이 있는 블록이고 다른 하나는 반환 값이 없는 블록입니다. 단점은 이렇게 하면 거의 동일한 블록이 많이 있는 혼란을 야기할 수 있다는 것입니다.

c) 하나의 블록을 변경합니다. 사용자가 반환 값의 존재 여부를 선택할 수 있는 드롭다운, 체크박스, 기타 컨트롤을 사용합니다. 그런 다음 블록은 옵션에 따라 도형을 변경합니다. 이에 관한 예는 Blockly의 목록 액세스 블록에서 확인할 수 있습니다.

d) 값을 먹습니다. 첫 번째 앱 인벤터 버전은 연결된 값을 소모하는 특수 파이프 블록을 만들었습니다. 사용자는 이 개념을 이해하지 못했으며, App Inventor의 두 번째 버전에서는 파이프 블록을 삭제하고 대신 사용자가 단순히 버리는 변수에 값을 할당하도록 권장했습니다.

권장사항: 전략마다 장단점이 있으므로 사용자에게 적합한 전략을 선택하세요.

8. 증가하는 블록

특정 블록에는 가변적인 입력 수가 필요할 수 있습니다. 임의 숫자 집합을 합산하는 추가 블록, elseif 절의 임의의 집합이 있는 if/elseif/else 블록, 초기화된 요소의 임의의 수가 있는 목록 생성자를 예로 들 수 있습니다. 여기에는 여러 가지 전략이 있지만 각각 장단점이 있습니다.

a) 가장 간단한 접근 방식은 사용자가 더 작은 블록으로 블록을 구성하도록 하는 것입니다. 예를 들어 두 개의 숫자 덧셈 블록을 중첩하여 세 개의 숫자를 더할 수 있습니다. 또 다른 예는 if/else 블록만 제공하고 사용자가 이러한 블록을 중첩하여 elseif 조건을 만들도록 하는 것입니다.

이 접근 방식의 장점은 초기 단계의 단순성 (사용자와 개발자 모두)입니다. 단점은 중첩이 많은 경우 사용자가 코드를 읽고 유지하기가 매우 번거롭고 어려워진다는 것입니다.

b) 대안은 블록을 동적으로 확장하여 끝에 항상 하나의 자유 입력이 있도록 하는 것입니다. 마찬가지로 블록은 끝에 여유 입력이 2개 있으면 마지막 입력을 삭제합니다. 이것이 App Inventor의 첫 번째 버전에서 사용한 접근 방식입니다.

블록이 자동으로 증가하여 App Inventor 사용자는 몇 가지 이유로 싫어했습니다. 첫째, 항상 무료로 입력할 수 있었고 프로그램이 '완료'되지 않았습니다. 둘째, 스택 중간에 요소를 삽입하면 수정사항 아래의 모든 요소를 연결 해제했다가 다시 연결해야 하므로 불편했습니다. 즉, 순서가 중요하지 않고 사용자가 프로그램의 구멍을 편안하게 만들 수 있다면 매우 편리한 옵션입니다.

c) 구멍 문제를 해결하기 위해 일부 개발자는 입력을 수동으로 추가하거나 삭제하는 블록에 +/- 버튼을 추가합니다. Open Roberta는 이러한 버튼 두 개를 사용하여 하단에서 입력을 추가하거나 삭제합니다. 다른 개발자는 스택 중간에서의 삽입과 삭제가 수용될 수 있도록 각 행에 두 개의 버튼을 추가합니다. 스택의 재정렬을 수용할 수 있도록 각 행에 위/아래 버튼을 두 개 추가하는 메서드도 있습니다.

이 전략은 블록당 2개의 버튼부터 행당 4개의 버튼에 이르기까지 다양한 옵션을 제공합니다. 한쪽 끝은 사용자가 필요한 작업을 할 수 없게 되고 다른 쪽 끝의 UI는 버튼으로 채워져 있어 우주선 엔터프라이즈의 다리처럼 보입니다.

d) 가장 유연한 접근 방식은 블록에 뮤테이터 도움말 풍선을 추가하는 것입니다. 이는 블록의 구성 대화상자를 여는 단일 버튼으로 표현됩니다. 요소는 원하는 대로 추가, 삭제 또는 재정렬할 수 있습니다.

이 접근 방식의 단점은 변형자가 초보자에게 직관적이지 않다는 단점이 있습니다. 뮤테이터를 사용하려면 몇 가지 형식의 지침이 필요합니다. 어린 아동을 대상으로 하는 블록 기반 애플리케이션은 뮤테이터를 사용해서는 안 됩니다. 한 번 배운 것은 파워 유저에게 매우 유용한 기능입니다.

권장사항: 전략마다 장단점이 있으므로 사용자에게 적합한 전략을 선택하세요.

9. 클린 코드 생성

고급 Blockly 사용자는 생성된 코드 (JavaScript, Python, PHP, Lua, Dart 등)를 확인하고 작성한 프로그램을 즉시 인식할 수 있어야 합니다. 즉, 이 머신 생성 코드를 읽을 수 있도록 유지하려면 추가 작업이 필요합니다. 불필요한 괄호, 숫자 변수, 잘린 공백, 상세 코드 템플릿은 모두 우아한 코드를 생성하는 데 방해가 됩니다. 생성된 코드에는 주석이 포함되어야 하며, Google의 스타일 가이드를 준수해야 합니다.

권장사항: 생성된 코드에 대해 자랑스럽게 생각하세요. 사용자에게 보여주세요.

10. 언어 의존성

클린 코드를 원하는 부작용은 Blockly의 동작이 크로스 컴파일된 언어의 동작 방식 측면에서 주로 정의된다는 것입니다. 가장 일반적인 출력 언어는 자바스크립트이지만, Blockly가 다른 언어로 크로스 컴파일하는 경우 두 언어에서 정확한 동작을 유지하기 위해 부당한 시도를 해서는 안 됩니다. 예를 들어 자바스크립트에서 빈 문자열은 false이지만 Lua에서는 true입니다. Blockly의 코드가 타겟 언어와 관계없이 실행되도록 단일 동작 패턴을 정의하면 GWT 컴파일러에서 나온 것처럼 보이는 코드를 유지할 수 없게 됩니다.

권장사항: Blockly는 언어가 아닙니다. 기존 언어가 동작에 영향을 주도록 허용하세요.