Допустим, у нас стоит задача получать в программу ссылку на Database Connection, причем, он не передается в качестве параметра, но в зависимости от случая это должен быть разный Connection. Использование шаблона Singleton в таком случае нецелесообразно.
Но в Smalltalk имеется достаточно штатных средств, чтобы изобрести необходимое решение. Предлагается паттерн под названием - переменные с динамической областью видимости.
Использование:
DynamicBinding withValue: someValue execute: ["..." variable := DynamicBinding defaultValue. "..." ].
Значение переменной someValue, переданное таким образом, можно получить в любом методе, вызванном из этого блока.
Например:
" задаем anObject в качестве текущего значения и вызываем someMethod " DynamicBinding withValue: anObject execute: [aFoo someMethod]. Foo>>someMethod " вызываем еще один метод " self bar anotherMethod Bar>>anotherMethod " DynamicBinding defaultValue возвращает объект anObject " self use: DynamicBinding defaultValue
Естественно, допускается использование и вложенных блоков с заданием динамической переменной. При этом значение "вложенной" переменной перекрывает значение "внешней" только для внутреннего блока. То есть, при выходе из вложенного блока автоматически "восстанавливается" прежнее значение.
Приведенный выше пример подходит, когда нужно передать значение только одно объекта, такого как Connection. Если необходимо передавать несколько значений, то нужно использовать DynamicBindingMap. Пример:
(DynamicBindingMap new) key: #varName1 value: value1; key: #varName2 value: value2; execute: ["..." value := DynamicBinding valueFor: #varName1. "..."]
Если переменной с запрошенным именем не существует, то будет возвращен nil.
Реализацию для VisualWorks можно взять здесь.