TheSpecUIframework:Chapter 02

From 흡혈양파의 번역工房
Revision as of 13:19, 17 August 2017 by Onionmixer (talk | contribs) (TheSpecUIframework 2장 내용 완료)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
처음 사용 및 예제

처음 사용 및 예제

이 책을 시작하기 위해 몇 가지 예제를 이용함으로서 Spec 의 사용법을 설명합니다. 먼저 작지만 완전한 사용자 인터페이스를 작성한 이후에, 기존 위젯을 구성하는 방법에 대한 몇 가지 예를 보여드리겠습니다. 이 예제들을 통해 기본 사용자 인터페이스를 구축 할 수 있습니다.


이 장을 끝낸 뒤에 Spec 위젯의 재사용에 대한 다음 장을 읽어보시기 바랍니다. Spec 위젯의 핵심 입니다. 이 두 장을 읽는다면 Spec 사용자 인터페이스를 의도 한대로 구성 할 수 있게 됩니다. 이 책자의 나머지 부분을 참고 자료로 사용할 수는 있지만, 그럼에도 불구하고 다른 장들에 대해서도 간략하게 살펴볼 것을 권장합니다.


고객 만족 UI

Spec UI 의 첫 번째 예제에서는 간단한 고객 만족도 UI를 구성해서, 사용자가 세 가지 버튼 중 하나를 클릭하여 서비스에 대한 피드백을 제공 할 수 있도록 합니다. (고객의 반응(피드백)을 기록하고 처리하기는 해야 하지만, 이 문서의 범위를 벗어나게 됩니다).

그림 2-1에서 UI의 스크린 샷을 확인할 수 있습니다.
그림 2-1 고객 만족 UI 스크린샷


UI 및 변수 접근자(accessors) 클래스 만들기

Spec 의 모든 사용자 인터페이스는 ComposableModel 의 하위 클래스이므로, UI 를 만드는 첫 번째 단계는 하위 클래스를 만드는 것부터 시작됩니다.

ComposableModel subclass: #CustomerSatisfaction
	instanceVariableNames: 'buttonHappy buttonNeutral buttonBad screen'
	classVariableNames: ''
	package: 'Spec-BuildUIWithSpec'


클래스의 인스턴스 변수는 UI 에 포함 된 위젯을 포함합니다. 이 예제에서는 세 개의 버튼과 텍스트 화면이 있습니다. 이러한 위젯들의 인스턴스 변수에 대한 접근자도 정의해야하며, Spec 인터프리터는 UI 구성 과정에서 이를 사용합니다.


UI 위젯의 인스턴스 변수에 대한 접근자 생성을 항상 기억하십시오.


이 클래스의 메소드는 초기화 및 구성을 제공합니다. label 및 action 뿐만 아니라 상호 작용의 논리도 포함됩니다. GUI의 기본 설계, 즉 위젯이 배치되는 방식은 클래스 측면의 메소드에 의해 정의됩니다.[1]


하위 위젯 인스턴스화 및 구성

ComposableModel 의 하위 클래스는 사용자 인터페이스에서 사용되는 위젯을 인스턴스화하고 구성하는 initializeWidgets 메소드를 정의 할 책임이 있습니다. 이부분에 대해서 차근차근히 살펴보도록 하겠습니다. 먼저 위젯 인스턴스화를 살펴보겠습니다:

CustomerSatisfaction >> initializeWidgets

	"widget instantiation"
	screen := self newLabel.
	buttonHappy := self newButton.
	buttonNeutral := self newButton.
	buttonBad := self newButton.


ComposableModel 은 표준 위젯 (newButton, newCheckBox, newDropList, ...) 생성을위한 메시지를 정의합니다. 이 모든 것은 widget 프로토콜에 정의되어 있습니다.


UI 의 일부인 위젯을 인스턴스화하려면 new 를 호출하지 마십시오.


위젯을 인스턴스화하는 또 다른 방법은 클래스를 인수로 사용하여 instantiate: 메시지를 사용하는 것입니다. 예를 들자면 다음과 같은 코드가 됩니다. screen := self instantiate: LabelModel. 이 코드는 비표준 위젯을 인스턴스화 할 수 있게 하지만, 당연히 표준 위젯에도 사용될 수 있습니다.


두 번째로 UI의 버튼을 구성해 보겠습니다. label: 메시지는 레이블을 정의하고 icon: 메시지는 레이블 근처에 표시 될 아이콘을 지정합니다. 이제부터 보여드릴 코드는 Pharo 6 를 위한 것입니다. Pharo 5 에서 작동시킨다면 자신의 iconNamed: 를 Smalltalk UI 아이콘 iconNamed: 로 바꾸는 작동을 하게 됩니다.

[ ... continued ... ]
	"widget configuration"
	screen label: 'Please give us your feedback.'.
	buttonHappy
		label: 'Happy';
		icon: (self iconNamed: #thumbsUp).
	buttonNeutral
		label: 'Neutral';
		icon: (self iconNamed: #user).
	buttonBad
		label: 'Bad';
		icon: (self iconNamed: #thumbsDown).


세번째 이자 마지막으로, 포커스 순서를 정의하는 것은 키보드로 탐색하는 경우에 유용합니다.

[ ... continued ... ]
	"specification of order of focus"
	self focusOrder
		add: buttonHappy;
		add: buttonNeutral;
		add: buttonBad


ComposableModel 서브 클래스는 initializePresenter 메소드를 정의 할 수도 있습니다. 이 메소드의 목적은 서로 다른 위젯 간에 상호 작용을 구성하는 것입니다.

CustomerSatisfaction >> initializePresenter

	buttonHappy action: [ screen label: buttonHappy label ].
	buttonNeutral action: [ screen label: buttonNeutral label ].
	buttonBad action: [ screen label: buttonBad label ].


action: 메시지를 사용하여 버튼을 클릭 할 때 수행 할 작업을 지정합니다. 이 경우 화면에 표시되는 내용을 변경하여 선택 사항이 등록되었다는 피드백을 제공합니다. action: 메시지는 버튼 API의 일부입니다. 다른 상황에서는 지정된 이벤트가 발생하면 다른 메시지를 위젯 서브 파트로 보내도록 지정합니다.


요약하자면, '자체적인' 위젯 설정은 initializeWidgets 에 들어가며, '외부와 연동되는' 부분의 위젯 설정은 initializePresenter 에 들어갑니다.


위젯은 이제 정의 및 구성되었지만 UI에서의 배치가 지정된 것은 아닙니다. UI 에서의 배치는 클래스 측 메소드인 defaultSpec 의 역할입니다.

CustomerSatisfaction class >> defaultSpec
	^ SpecLayout composed
		newRow: [ :row |
			row add: #buttonHappy; add: #buttonNeutral; add: #buttonBad ]
		origin: 0 @ 0 corner: 1 @ 0.7;
		newRow: [ :row | row add: #screen ]
		origin: 0 @ 0.7 corner: 1 @ 1;
		yourself


이 레이아웃에서는 UI에 두 개의 행을 추가하게 됩니다. 하나는 버튼이고 다른 하나는 텍스트 화면입니다. 위젯 레이아웃을 정의하는 것은 여러 가지로 가능한 요구 사항을 가진 복잡한 프로세스이므로 이 장에서는 레이아웃 사양에 대해 자세히 이야기하지는 않을 것입니다. 자세한 내용은 5장을 참조해 주세요.


add: 메시지의 인수는 접근자의 심볼이 됩니다. 왜나하면 Spec 인터프리터가 레이아웃을 작동시킬 때 위젯을 불러오기 위해서 이 메서드를 호출하기 때문입니다.


제목 및 창 크기를 정의하기, UI 의 열기 및 닫기

창의 제목과 초기 크기를 설정하려면 두 가지 메서드를 정의해야합니다.:

CustomerSatisfaction >> title
	^ 'Customer Satisfaction Survey'.

CustomerSatisfaction >> extent
	^ 400@100


title 메서드는 제목으로 사용될 문자열을 반환하고 extent 메서드는 창의 크기를 지정하는 포인트를 반환합니다. UI 를 열려면, 클래스의 인스턴스를 만들어야하며 openWithSpec 메시지를 보내야합니다. 메시지를 보내면 창이 열리며, 열린 창에서는 코드를 닫을 수 있는 WindowModel 인스턴스가 반환됩니다.

 | ui |
 ui := CustomerSatisfaction new openWithSpec.
 [ ... do a lot of stuff until the UI needs to be closed ...]
 ui close.


대화 상자를 열거나 about 텍스트를 설정하는 방법등 창 관리에 대한 추가 정보는 6 장을 참고해주세요.


이것으로 Spec 사용자 인터페이스의 첫 번째 예제를 마치겠습니다. 이제부터는 이러한 사용자 인터페이스에서 사용할 수 있는 다른 위젯을 구성하는 방법에 대한 예제가 계속됩니다.


Fun with Lists

위젯을 구성하는 방법을 보여주는 명확한 예제로서, 서로 다른 배경색을 사용하는 목록과 아이콘을 보여주는 목록의 두 가지 예제를 확인할 수 있습니다.


이 예제는 Spec의 두 가지 중요한 기능을 보여줍니다:

  1. 모든 위젯은 창에서 열 수 있습니다. 이는 위에 표시된 것처럼 복잡한 UI 와 표준 위젯 사이에 근본적인 차이는 없기 때문입니다.
  2. 모든 위젯은 설정 가능하며, 설정에 대한 메소드는 api 프로토콜로 분류됩니다.


항목의 배경으로 색상 등록하기

그림 2-2 와 같이 요소(elements)의 배경색이 각각 다르게 되어있는 ListModel 예제부터 시작하겠습니다. 목록에있는 항목은 각각 다른 색상의 이름이며, 목록에는 해당 색상의 배경을 사용하여 목록이 표시됩니다.


다음의 코드는 이런 내용이 어떻게 수행되는지를 보여줍니다:

 | registeredColorsList |
 registeredColorsList := ListModel new.
 registeredColorsList
	items: Color registeredColorNames;
	backgroundColorBlock: [ :item | Color named: item ];
	title: 'Registered colors'.
 registeredColorsList openWithSpec


이렇게 하면 ListModel API 의 일부인 다음 메시지가 표시됩니다.

그림 2-2 배경색이 수정된 목록의 스크린샷


  • items: 메시지는 목록의 요소를 설정합니다.
  • backgroundColorBlock: 메시지는 현재 요소의 배경색을 결정하기 위해 실행되어야할 블록을 지정하게 됩니다. 단일 매개 변수, 즉 목록 항목이있는 블록을 사용합니다.
  • title: 메시지는 목록이 들어있는 창의 제목을 설정합니다.


아이콘의 목록

두 번째 예제에서는 현재 테마의 아이콘과 IconListModel 에 대한 해당 셀렉터(selector)를 포함하는 목록을 보여줍니다. 목록 항목은 아이콘 이름과 아이콘 자체 사이의 연관(associations)이며, 목록에 표시된 텍스트는 아이콘 이름이고, 목록에 표시된 아이콘은 아이콘 그 자체입니다. 또한 항목의 이름에 따라 알파벳순으로 항목을 정렬합니다.

 | iconList |
 iconList := IconListModel new.
 iconList
	items: Smalltalk ui icons icons associations;
	displayBlock: [ :assoc | assoc key];
	sortingBlock: [ :assocA :assocB | assocA key < assocB key ];
	icons: [ :assoc | assoc value ];
	title: 'Availiable icons for the current theme.'.
 iconList openWithSpec


그림 2-3 아이콘 목록의 스크린 샷


ListModel API 뒤에 따라오는 메시지에 주목해야 합니다:

  • displayBlock: 메시지는 도메인 특유의 항목을 수신하고 문자열처럼 목록에 표시 될 수있는 내용을 반환하는 블록을 사용합니다.
  • sortingBlock: 메시지는 목록을 표시하기 전에 목록의 요소를 정렬하는 작업에 사용될 블록을 이용합니다.


결론

이 장에서는 Spec 사용자 인터페이스에 대한 첫번째 접근을 제공했습니다. 먼저 Spec 을 사용해서 사용자 인터페이스를 작성하는 단계와, 기존 Spec 위젯을 구성하는 방법에 대한 두 가지 예제를 확인할 수 있었습니다.


Spec 사용자 인터페이스의 더 많은 예제는 Pharo 이미지 자체에서 찾을 수 있습니다. 모든 Spec 사용자 인터페이스는 ComposableModel 의 하위 클래스이므로 찾기 쉬우며, 각각의 예제 사용자 인터페이스는 예제로 사용될 수 있습니다. 또한 모든 위젯은 독립 실행 형 창으로 열 수 있으며, 설정 메소드는 API 프로토콜로서 분류되기 때문에 위젯 및 사용자 인터페이스에 대한 실험을 쉽게 실험해볼 수 있습니다.


Spec 위젯의 재사용에 대해서는 다음 장(chapter)을 읽는 것이 좋습니다. Spec 위젯의 핵심입니다. 다음장을 통해 얻게될 지식을 사용해서 재사용을 통해 UI를 빠르게 작성하고, 자신의 UI를 다시 사용할 수 있도록 도와줍니다. Spec 의 세 가지 주춧돌(pillars) 대한 그 이후의 장은 Spec 의 기능에 대해서 보다 완전한 개요를 제공하며, 반드시 전부를 읽어볼 가치가 있습니다. 이후의 내용들은 특정 문제 또는 사용 사례에 대한 참조 자료로 더 많이 쓰일 수도 있지만, 전체적으로 읽어두는것을 권장합니다.


Notes

  1. Smalltalk 은 class 측면과 instance 측면의 2가지 측면(side)으로 메서드를 가질 수 있습니다. 이는 다른 언어에서 "클래스 메서드" 라고 불리는것과 같습니다