SmalltalkObjectsandDesign:Chapter 11
- 제 11 장 Model-View-Controller 의 훌륭함
Model-View-Controller 의 훌륭함
애플리케이션이나 시스템의 사용자 인터페이스(UI)는 사용자가 상호작용하는 모든 것-화면, 음향, 메뉴, 키보드, 마우스 등등-으로 구성된다. 이번 장에서는 사용자 인터페이스를 먼저 논하고자 한다; 이러한 논의는 제 13장으로 결론을 맺는데, 제 13장에서는 실제로 만족스러운 사용자 인터페이스를 디자인하는 데에 직면하는 실질적인 도전과제를 강조한다.
여기서는 먼저 한가지 목표를 설정하고자 한다: 바로 UI를 가능한 한 실용적으로 비-UI(non-UI) 소프트웨어 요소로부터 분리시키는 것이다. 이러한 분리 개념을 Model-View-Controller(MVC) 라고 하는데, 기원은 1970년대로 거슬러 올라가며, 개체 지향 사용자 인터페이스 디자인의 역사에서 가장 중요한 사건에 속한다.
Model-View-Controller 예제
누군가 컴퓨터화된 카운팅 툴이 필요하다고 상상해보자. 여기 두 개의 애플리케이션을 이용할 수 있다:
두 애플리케이션은 분명 값을 다르게, 하나는 디지털식으로, 나머지는 아날로그식으로 표시한다. 두 종류의 디스플레이는 두 종류의 View 로 취급하면 된다. 엄밀히 말해 View 라는 것은 정보를 표시하는 방법에 불과하다. 현재 digital View 는 9 를 표시하고 analog View 는 3 을 표시한다.
두 애플리케이션을 화면에 함께 나타냈지만 사실상 둘 사이에 연결관계는 없다. 각자 메뉴를 이용해 서로와 상관없이 숫자를 증가시킬 수 있다. 따라서 애플리케이션은 각자 기본이 되는 counter 객체-각각 increment와 decrement 메서드, 그리고 현재 값을 나타내는 인스턴스 변수를 가진 객체-에 의존한다.
이러한 counter 의 두 인스턴스는 model 객체로 알려져 있는데, 위의 View 가 서로 독립적으로 작용하듯 이 model 객체도 서로 독립적으로 작용한다. model 객체들은 기본이 되는 애플리케이션-이번 예제에서는 기본이 되는 카운터-의 상태를 변경하고 유지하는 책임이 있다. 모델은 정보가 어떻게 표시되는지 알지 못한다; 즉, 그들의 뷰를 알지 못한다. 모델은 컴퓨터 디스플레이에 표시되지 않는다.
View 와 그 모델을 연결하는 매커니즘을 짧게 논하겠지만 다른 가능한 구성을 먼서 고려해보자: 두 개의 뷰는 하나의 model 객체를 공유할 수 있다. 두 개의 View 는 정확히 같은 방식으로 작용한다: 하나를 증가시키면 나머지도 증가하는데, 하나의 동일한 model 객체에 대한 다른 관점에 불과하기 때문이다. 두 가지 View 를 소개하겠다:
두 개의 뷰가 공유하는 model 객체는 다음과 같다:
여기까지 우리가 고려한 모든 카운터는 메뉴 선택을 이용해 동일한 방식으로 작동한다. 다음 단계는 버튼, 즉 완전히 다른 입력 매커니즘을 소개하겠다:
이 애플리케이션은 지금까지 살펴본 유형과 동일한 digital view 를 가지며 앞의 것과 동일한 유형의 model 을 가지지만 Controller-입력 매커니즘의 기술적 용어-의 유형은 다르다. 이러한 유형의 Controller 는 이 카운터 애플리케이션을 생성하는 analog view 와도 관련이 있을 수 있다.
이론상 애플리케이션의 디자인을 독립된 요소-Model, View, Controller-로 분해할 수 있다. 사실상 그러한 분해는 당신이 작업해야 하는 클래스의 프레임워크에 따라 다소 달라진다. 예를 들어, 완전한 3자간(full three-way) 분해는 다른 스몰토크 환경보다는 VisualWorks에서 발생하기 쉽다는 사실을 추후에 살펴볼 것이다.
Controller 는 입력 이벤트를 처리하는 객체로, View 는 출력 이벤트를 처리하는 객체로 생각할 수 있겠다. 좀 더 정밀히 말해, Controller 는 마우스 버튼의 클릭처럼 사용자가 생성하는 이벤트를 처리하고, View 는 모델이 생성하는 이벤트, 즉 카운터 값의 증가와 같은 이벤트를 처리한다. View 는 look(모양)을 제공하고 Controller 는 feel(느낌)을 제공한다. Model 은 View 와 Controller 의 기반이 되며, 다음 절에서 볼 수 있듯이 이상적인 Model 은 View 또는 Controller 와 독립적이다. Model 은 View 또는 Controller 에 대해 알지도 못할 뿐더러 전혀 신경 쓰지 않는다.
연습
아래 화면은 여러 개의 카운터 애플리케이션을 보여준다. 상단 두 개의 카운터는 간단하게 마우스 클릭으로 작동한다: 왼쪽 마우스 클릭은 계수를 증가시키고 우측 클릭은 감소시킨다.
❏ 얼마나 많은 유형의 Model 이 존재하는가?
❏ 얼마나 많은 유형의 View 가 존재하는가?
❏ 얼마나 많은 유형의 Controller 가 존재하는가?
❏ 얼마나 많은 모델의 인스턴스가 존재하는가?
MVC가 작용하는 방법
아래는 사용자가 MVC 분해를 기반으로 애플리케이션과 상호작용하는 방법을 나타낸 것이다:
view 객체는 정보를 사용자에게 전달하고 controller 객체는 사용자의 입력을 받아들인다. 사용자는 model 객체와 직접 접촉을 하지 않는다; 뷰와 컨트롤러와의 상호작용으로부터 모델의 존재와 특성을 상상할 뿐이다. (그녀가 어떻게, 무엇을 상상하는지가 바로 제 13장의 주제이다.)
전통적 MVC에서 이 세 가지 유형의 객체들 간 관계는 아래와 같이 표시된다:
view 와 controller 는 서로 뿐만 아니라 그들의 model 을 참조하는 인스턴스 변수도 갖고 있음을 볼 수 있다. 그들은 자신의 model 을 알고 있다. 하지만 model 은 view 와 controller 를 알지 못한다. model 은 그 view 나 controller 를 가리키는 명시적인 인스턴스 변수를 갖고 있지 않다. 이는 결정적인 누락이다. 기본이 되는 애플리케이션은 사용자 인터페이스가 정보를 표시하거나 입력을 해석하는 방법에 대한 지식 없이도 기능해야 한다. 애플리케이션은 그것에 어떤 유형의 view 또는 controller 가 부착되어 있는지, view 나 controller 의 다수가 부착되어 있는지, 또는 시간이 지나면서 다른 view 나 controller 가 부착되어 있는지에 대해서도 알아선 안 된다. MVC 의 본질은 사용자 인터페이스 컴포넌트로부터 model 을 근본적으로 분해하는 데에 있다.
model 이 그 view 나 controller 를 참조하는 인스턴스 변수를 갖고 있지 않다면 어떻게 그 상태의 변경을 그들에게 알릴까? 다시 말해, mode 이 view 나 controller 를 알지 못하게 하면서 변경 내용은 어떻게 알릴 수 있을까? 이에 대한 답은, 의존성이라는 숨겨진 관계를 통해 간접적으로 알린다는 데에 있다: model 의 종속자(dependent)들은 위에 점선 화살표로 표기되어 있다. model 이 그 종속자로 전달하고자 하는 변경내용을 지속할 때마다 model 은 itself-self broadcast[1]-로 메시지를 전송하고, 이는 최종적으로 자신의 종속자들-dependent update-에게 메시지를 전송하게 된다. 오히려 종속자가 자신을 업데이트하기 위해 무엇을 하길 원하는지 결정한다; 이것이 위의 update 메서드의 기능이다. 카운터 예제의 경우, view 의 update 메서드는 해당되는 model 로 메시지를 전송하여 큐가 관련된 표시내용을 새로고침(refresh)할 수 있는 카운터의 현재 값을 불러올 것이다.
대략적으로 말하자면, 의존성 관계를 구현하는 데에는 두 가지 매커니즘이 있다. 하나는 전역 dictionary 을 사용하는데, 이는 model 을 키(key)로 가지고 각 키(model)와 연관된 값은 model 의 종속자 컬렉션에 해당한다. broadcast 메서드는 문제가 되는 model 을 dictionary에서 검색한 후 model 과 연관된 각 객체로 update 메시지를 전송한다. 다음 소개할 예제가 이러한 매커니즘을 보인다.
두 번째 매커니즘은 의존 객체들의 정렬된 컬렉션을 참조하는 고유의 dependents 인스턴스 변수를 각 model 에게 제공한다. 그리고 broadcast 메서드는 이 컬렉션의 각 객체로 update 메시지를 전송한다. 의존성에 대한 코드를 작성하여 model 에 대한 새 클래스를 구성할 때마다 알리는 방법을 원하지는 않을거고, 두 번째 매커니즘을 채택한다면 필요한 코드를 Model 이라는 추상 클래스에 한 번 작성한 후 그로부터 자신의 model 클래스를 모두 서브클래싱해야 한다. 이러한 기법은 우리가 원하는 관계를 숨긴다; model 객체를 빌드하는 애플리케이션 프로그래머들은 dependents 인스턴스 변수가 존재한다는 사실을 몰라도 된다.
두 번째 매커니즘을 다듬으면, 주어진 이벤트에 대한 응답으로 메시지 무리가 방송(broadcast)되는, 좀 더 예리한 방송 형태를 제공한다. 이러한 형태는 이제 모든 주요 스몰토크 dialect 에서 이용할 수 있다 (125 페이지 표 참고). 예를 들어, VisualAge 의 AbtObservableObject 클래스는 단순한 dependents 인스턴스 변수를 완전히 없애버린다; 대신 이벤트를 키로 가지며 메시지 무리를 값으로 가지는 dictionary 같은(dictionary-like) 객체인 eventDependents 라는 인스턴스 변수를 갖는다. 따라서 AbtObservableObject 는 모든 객체에게 동일한 update 메시지가 전송되는 고정된 방송(broadcast) 대신 그 이벤트 중 하나와 연관된 메시지 무리를 선택적으로 방송할 수 있다. 그리고 이러한 메시지들의 이름이나 수신자는 어떤 것도 가능하다. 사실상 방송은 구조적으로 정밀하다.
이러한 예리한 방송 형태는 event notification(이벤트 통지)라고 불리기도 한다. 이벤트 통지는 점점 더 유명해지고 있으며, 머지않아 기존의 기본 방송 형태를 대체할지도 모른다.
연습: 오리지널 의존성 매커니즘
❏ 모든 주요 스몰토크 dialect 는 객체가 서로 의존하도록 해주는 일반 의존성 매커니즘을 지원한다. 대부분의 스몰토크에서 이러한 매커니즘은 Object 의 클래스 변수인 Dependents 를 사용한다. Dependents 를 검사하라[2]. 그것은 어떤 유형의 객체이며, 현재 무엇을 포함하는가?
❏ 아래를 실행하라:
X := Penguin new. "Any object will do!"
X addDependent: 17.
X addDependent: 12.
Dependents inspect.
이제 Dependents 는 무엇을 포함하고 있는가?
❏ 다음으로 아래를 실행하라:
X broadcast: #update.
스몰토크는 업데이트를 방송하지만 당신은 아무 것도 보지 못한다. 이는 정수가 update 에 응답하지 않기 때문이다. 이제 아래를 body 로 하는 update 를 Integer 에 작성하라:
Transcript cr;
show: 'I am ', self printString.
(IBM Smalltalk 의 Professional 버전은 메서드를 새 애플리케이션 에디션에 넣도록 요구할 수도 있다. "scratch" 에디션을 포함해 어떤 에디션이든 충분하다.) 다시 시도해보라:
X broadcast: #update.
이러한 일반 의존성 매커니즘은 쓸 만하지만 객체 지향 표준에 따르면 그다지 바람직하게 캡슐화되지 않았다. 결국 어떤 객체든 Object 객체 안쪽의 Dependents 클래스 변수로 접근할 수 있기 때문이다. 의존성 매커니즘을 사용하고 싶다면 객체가 자신의 종속자를 캡슐화하는 곳에서 빌드하거나 재사용하는 방도를 고려해보라. 주요 스몰토크 dialects 에는 그러한 매커니즘이 이미 포함되어 있다. (125 페이지 표 참고.)
MVC: 장점과 단점
깔끔한 MVC 분해는 디자이너를 정직하게 만들어준다. 이는 디자이너로 하여금 문제를 구분하도록 강요하는데, 소프트웨어의 기본 목표에 해당한다. 그는 기본이 되는 모델이 화면에 나타나는 데에 대해 염려하지 않고 모델의 응집도(coherence)에 초점을 둘 수 있다 (이 주제에 관한 상세한 정보는 제 13장에 소개). 반대로 디자이너는 model 객체를 재프로그래밍할 필요 없이 모델을 표현하는 새로운 방법들은 개발할 수 있다. 짧게 말하자면 사용자 인터페이스와 모델의 개발을 따로 진행할 수 있다는 말이다. 그리고 나면 객체는 훨씬 더 작고 덜 복잡해지며, 재사용 기회는 더 증가한다.
MVC 는 또한 하나의 플랫폼에서 다른 플랫폼으로 애플리케이션을 이식하는 경로를 제공한다: model 객체들은 문제를 최소화한 후 이동해야 한다-훌륭한 model 은 플랫폼 특정적인 코드로 채워지지 않는다. 따라서 이식(porting) 문제는 UI 코드만 재작성하면 되도록 축소된다. 이로 인한 혜택은 애플리케이션 내 model 코드와 UI의 상대적 비율에 따라 좌우된다. 위의 카운터 예제는 간단한 model 이기 때문에 혜택이 거의 미비하다. 하지만 알고리즘 내용이 풍부한 네트워크 시뮬레이션과 같은 애플리케이션에서는 이득이 상당하다. 어떤 경우든 이상적으로 말하면, 이식을 책임지는 프로그래머는 기본이 되는 애플리케이션 또는 문제에 대해 알거나 학습할 필요가 없을 것이다.
순수한 의미의 MVC 분리는 바람직하면서 높은 목표이다. 몇 가지 장애물을 적자면 다음과 같다.
- 단순한 렌더링(rendering). MVC에서 우리는 model 객체가 자신의 존재와 상관 있는 것은 무엇이든 알지 못하도록 유지하기 위해 노력한다. 엄격히 말하자면 그래픽 창에 픽셀의 원형 배열을 그리는 메서드, 심지어 'Circle' 이라는 철자를 쓰는 메서드를 이용해 circle 객체를 그리는 것조차 MVC에게는 진실되지 못할 것이다. 마찬가지로 이 순수주의자는 일자와 금액을 알려주는 문자열을 리턴시키는 checking account transaction 객체에 대해 메서드를 도전(다음 장에서 보게 될 예제와 같이)할 수도 있다. 그러한 메서드는 argument가 가는 모델이 아니라 뷰와 관계가 있다. 하지만 이러한 렌더링 메서드로 model 객체를 더럽히지 않기로 고집할 경우, 렌더링의 책임이 있는 또 다른 객체층으로 대가를 치뤄야 할 것이다. 이는 상대적으로 사소한 MVC 위반에 대한 과장된 반응이 되기도 한다.
- 유효성과 제약 확인. 사용자가 가령 전화번호를 입력하는 화면에서는 UI에게 번호의 구조-국가 코드, 지역 또는 도시 코드, 번호, 구내전화-가 수용 가능한지 검증할 기회가 주어진다. UI는 심지어 다른 필드, 예를 들어 국가 이름 필드를 새로고침할 수도 있다. 그러한 확인에서 UI가 발휘하는 지식이 비즈니스 특정적일수록-어떤 국가가 수용되는지, 전화번호에 번호나 문자를 허용할 것인지 등-MVC 분해는 덜 순수해진다. 오늘날 UI를 좀 더 강력하게 만드는 데 발생하는 불이익은, 비즈니스가 발전하면서 모델 코드 뿐만 아니라 UI 로직도 재작성해야 한다는 점이다.
- 부분 새로고침. 전형적인 MVC에서는 UI가 특정 변경내용을 모델에게 알려주면 모델이 UI로 일반 업데이트를 다시 방송한다. 그리기 애플리케이션의 경우, UI는 모델로부터 모든 그림 요소를 불러옴으로써 업데이트함과 동시 캔버스는 비우고, 이후에 전체 캔버스를 새로고침한다. 하지만 특정 변경내용이 캔버스의 극히 일부에만 영향을 미치는 경우, 전체 캔버스의 비우기(blanking)와 새로고침(refreshing)은 속도가 느려지고 산만해진다. 일반적인 MVC는 소량으로 영향을 미친 일부만 새로고침할만큼 유연하지 않다; 부분적 새로고침에는 뷰와 모델 간 밀접한 협력이 요구된다. 뷰는 여전히 변경내용을 모델에게 알리지만 모델로부터 필요로 하는 그러한 요소들은 선택적으로 가져와야 하며, 캔버스의 변경된 부분만 새로고침해야 한다. 이러한 최적화가 모델의 방송 의무를 제해주진 않지만-결국 다른 뷰들도 존재할 것이므로-현재 활성화된 뷰는 방송을 무시하고, 우리가 피하려 했던 일, 즉 스스로를 비우고(blanking)하고 완전히 새로고침함으로써 응답하지 않도록 해야 한다.
- 드래그 앤 드롭. 사용자가 화면에 거쳐 아이콘을 드래그하면 아이콘은 그것이 놓여지는 타겟마다 자신의 모양을 변경할 수 있다. 예를 들어, 드롭이 무효한(illegal) 경우 다수의 UI는 아이콘을 "Do not enter" 부호로 변경한다. 드롭의 적격성(legality)은 보통 드래그하는 그래픽 요소가 특정 창에 놓이는지와 같이 간단한 사항에 따라 좌우된다. 하지만 적격성(legality)은 상상컨대, 기본이 되는 객체의 상태 등의 좀 더 복잡한 조건에 따라 좌우될 수도 있다. 환자가 특정 약물에 알러지 반응이 있는 경우 Prescription(처방) 아이콘을 환자 아이콘에 드롭하지 못할 수 있다; 편지에 수신인이 표시되어 있지 않을 경우 메일 박스에 편지를 드롭할 수 없을 것이다; 고객이 위험 보험에 해당한다면 고객에게 보험 증권을 드롭하지 못할 것이다. 이러한 상황에서 기본이 되는 model 객체들은 유일하게 관련된 상태 정보를 알고 있기 때문에 협상에 참여해야 한다. 시각적 결과(Visual artifact)에 불과한 아이콘 객체들은 이러한 상황에서 도움이 될만큼 똑똑하지는 못하다; model 객체에 어떤 질문을 해야 하는지조차 모른다. 방송 은유(metaphor)와 함께 MVC는 이렇게 세밀한 실시간 문제와 관련이 없다. 이 문제에 대한 해결책은 lawyer 객체를 사용하는 것이다 (233 페이지). Lawyer 객체는 아이콘을 비롯해 기본이 되는 model 객체를 모두 알고 있으며, 다른 아이콘과 model 객체 쌍을 나타내는 다른 lawyer 객체들과 협상한다. UI는 각 아이콘마다 하나의 lawyer를 나타내는 lawyer 컬렉션을 유지하며, lawyer는 그들이 대표하는 model 객체들 간 협상을 통해 아이콘이 서로에게 드롭될 것인지를 결정한다.
마지막 세 가지 장애물들은 방송이 때때로 너무 느리고 무겁다는 경험을 강조한다. 오늘날 컴퓨팅 시스템의 사용자들은 직접적 피드백을 기대한다; 모델이 view 객체들에게 일반화된 방송을 전달(issue)할 때까지 기다리지 못한다. 대신 view 객체는 이상적 MVC 분리(partitioning)에서보다 model 객체들과 훨씬 더 직접적으로 관여한다. MVC 가 모든 상황에서 충분한 것은 아니다.
어떤 경우가 MVC 가 되는가?
MVC라는 개념은 Trygve Reenskauge가 Xerox PARC 스몰토크 팀을 방문했을 당시 1978-1979년에 생긴 것으로, Smalltalk-80 제품에서 공식화된 이후 VisualWorks가 되었다3. Digitalk는 초기 DOS Smalltalk/V 제품에 동일한 개념을 기본적으로 전달하였고, 이는 이후에 MPD(모델-패인-디스패처)로 재명명되었다.
최근 controller 객체는 보통 view 객체로 흡수되어, 전형적인 MVC 3자 관계(threesome)는 2자 관계로 축소된다. 이에 관한 이론적 원리를 살펴보기 위해서는 위의 카운터 애플리케이션에서 푸시버튼 컨트롤러를 생각해보라. 이러한 컨트롤러에는 뷰와 같은 특성이 있다: 버튼이 눈에 보이고, 마우스를 클릭할 때 내려갔다가 올라온다는 점이다. 버튼 컨트롤러는 사실상 이미 뷰와 같은 객체로 바인딩되어 있고, 메시지는 절반은 컨트롤러로, 나머지 절반은 뷰로 구성된 사이를 왔다 갔다 하면서 그들의 행위를 조정한다. 컨트롤러는 보통 뷰와 컨트롤러 특성을 모두 갖고 있기 때문에 객체 지향 UI 클래스들은 주로 뷰와 컨트롤러를 한 종류의 객체로 합쳐서 프로그래머가 두 가지 객체 간 통신을 유지해야 하는 수고를 덜어준다.
뷰와 컨트롤러를 합치는 또 다른 이유는, 통합된 뷰-컨트롤러는 X-Windows, OS/2 Presentation Manager, Windows, Macintosh와 같은 네이티브 윈도잉 환경에서 발견되는 내장 사용자 인터페이스에 (스크롤바, 버튼, 메뉴 등) 자연스럽게 일치하기 때문이다. 처음에 없었던 뷰와 컨트롤러 구성 요소로 해체하는 것보다는 윈도잉 환경 상에 있는 프로그래밍 객체 계층이 기본이 되는 아키텍처를 반영하는 편이 더 간단하다.
이러한 현대식 뷰-컨트롤러 객체들은 뷰 또는 때때로 인터렉터(interactor)라는 이름으로 통한다. 애플리케이션을 전형적인 3자간 MVC 분해가 아니라 더 단순한 MV 형태로 분해한다:
짧게 말해, 뷰와 컨트롤러를 합치면 프로그래머의 업무를 단순화시키지만 모양과 느낌을 혼합하고 일치하는 데에서 유연성이 어느 정도 손실된다. 오늘날, 스몰토크를 기반으로 하든 C++를 기반으로 하든 대부분 UI 프레임워크들은 컨트롤러와 뷰를 합친다. 이러한 예로 MacApp, SmalltalkV, Interviews, IBM Smalltalk 에 사용되는 X/Motif 위젯을 들 수 있겠다. VisualWorks 는 전체 MVC 분리를 아직도 유지하고 있는 가장 주목할 만한 제품이다.
이제부터 MVC 분리 대신 MV 분리에 초점을 두겠다. 따라서 UI 개발자들의 가장 주된 소프트웨어 공학 의무는 모델과 뷰를 구분하는 일이다. 당신은 모델 행위가 뷰로 지나치게 침투하는 일이 발생하지 않도록 노력해야 한다. 강력한 GUI (그래픽 사용자 인터페이스) 빌더들은 이를 더 부추기는 경향이 있는데, 개발자들이 GUI 빌딩에 현혹되어 일관된 model 객체의 계층 디자인을 간과하는 경우가 종종 있기 때문이다.
120 페이지에서 암시한 바와 같이 MV 또는 MVC 분리에 적절한 broadcast 또는 의존성 매커니즘에는 여러 개가 있다. 아래 표는 주요 스몰토크 dialect에서 이용 가능한 다양한 분리방법을 보여준다:
VisualAge (IBM Smalltalk) |
Visual Smalltalk (Smalltalk/V) |
VisualWorks (Smalltalk-80) | |
추상 클래스 View, Controller (전체 MVC를 지원) |
없음 | 없음 | 있음 |
Object 에서 클래스 변수가 지원하는 의존성 |
Dependents | EventHandlers (구버전에서 Dependents) |
Dependents |
추상 클래스에서 인스턴스 변수가 지원하는 의존성 |
AbtObservableObject 는 메시지 클러스터를 방송함 (이벤트 통지로 알려짐)-a |
EventManager 는 메시지 클러스터를 방송함 (이벤트 통지로 알려짐) |
Model 이 update 와 같은 메시지(들)을 모든 종속자들에게 방송함-b |
- a 3.0 버전부터 AbtObservableObject가 아닌 서브클래스의 인스턴스들 또한 메시지 클래스를 방송할 수 있다. 이러한 프로토콜은 AbtObservableObject의 것과 동일하지만 메서드는 보조 클래스 AbtCLDTAdditions를 이용해 Object에서 구현된다.
- b ParcPlace-Digitalk는 결합된 VisualSmalltalk/VisualWorks 제품(offering)에서 EventManager 를 그 인스턴스 기반의 방송 프로토콜에 대한 기반으로 만든다.
Object 내의 클래스 변수는 빠르고 깔끔하지 않은 방송에는 편리하지만 어떤 객체로부터든 접근할 수 있기 때문에 사용을 피해야 한다. 따라서 이것은 우리가 일반적으로 바람직한 것으로 알고 있는 전역 변수에 버금간다. 이러한 매커니즘은 더 많은 메시지 전송을 수반하는데, 이는 많은 (어쩌면 너무 많은) 방송으로 인해 디자인의 성능을 저해할 수도 있다. 따라서 내장된 인스턴스 기반의 지원을 사용하거나 (표에서 마지막 행), 고유의 추상 클래스를 한 번 빌드하여 그로부터 서브클래싱할 수 있다.
방송에 실행 가능한 접근법은 많기 때문에 ANSI 표준화 위원회가 방송 또는 의존성 프로토콜을 향후 스몰토크 표준의 일부로 명시할 가능성은 거의 없다.