Уроки программирования на Smalltalk: создание объекта aPerson Статья #4
Автор: Jason Steffler
|
Краткое содержание этой статьиЕсли вы не читали предыдущие статьи, сначала обязательно прочтите введение. В этом месяце мы будем обсуждать создание объекта aPerson : как для этого использовать браузеры и некоторые принципы объектно-ориентированного программирования. Если вы хотите получить все статьи или получить информацию о будущих статьях, вы можете посетить страницу MST. Дальнейшую информацию по изучению Squeak можно найти здесь.В этом месяце я не буду использовать локальные связи (local links [LL]), так как они не использовались так часто, как я ожидал. Цитата дня"Самая большая проблема C++ сообщества сегодня - это использование Стандартного C++ так, как он был задуман, а не как прославленный C или жалкий Smalltalk."- Бьярн Страуструп (создатель языка C++), "Getting From The Past To The Future" , стр. 23 C++ Report, SIGS Ноябрь/Декабрь 1999 Том1 No.10 Создание объекта aPersonПрежде, чем мы начнем, вы, вероятно, захотите скачать файл со следующей версией ScopedBrowser , который мы рассмотрели в предыдущей статье. Если вы сохранили свой образ с браузером, не беспокойтесь о конфликтах, так как этот новый файл заменит 1 предыдущий ScopedBrowser ( см. статью 2 о том, как это делается) На этот раз мы рассмотрим еще несколько классов, они использовались для создания класса Person. И несколько классов для лучшего восприятия материала:
Теперь вернемся к созданию класса Person. Если вы ввели исходный код класса Person из статьи 2, то, возможно, вы захотите или удалить тот класс из системы или озаглавить этот пример как Person2, или JrsPerson (префикс с вашими инициалами), или что-нибудь типа того, чтобы избежать коллизий пространства имен (namespace collisions). Я удалю класс Person и создам новый, если вы решите последовать моему примеру, откройте ScopedBrowser, используя такую команду: ScopedBrowser openBrowserForArticle4 Вы увидите семь доступных вам категорий,
включая MakingSmalltalk-Article2. Если класс Person существует,
то он должен быть в этой категории. Щелкните левой кнопкой мыши
на классе Person, потом нажмите среднюю кнопку мыши и выберите пункт Remove.
Появится окошко с просьбой подтвердить ваш выбор.
Щелкните на кнопке yes. Вы увидите, что категория MakingSmalltalk-Article2
теперь пуста.
Object subclass: #ИмяКлассаПока не задумывайтесь о том, что такое общий словарь (pool dictionary) или переменная класса (class variable). Просто отредактируйте этот шаблон так, чтобы он выглядел как здесь: [ex1a] Object subclass: #PersonТеперь щелкните средней кнопкой мыши и выберите пункт меню accept. Вы заметите, что класс Person добавился к категории article 4. Теперь давайте добавим метод. Первый метод, который мы обсуждали в статье 2, был sing. Щелкните правой кнопкой мыши и в панели категорий методов выберите пункт new category...>new..., введите: Singing в качестве имени категории методов, потом щелкните на кнопке Accept. На кодовой панели вы заметите хороший шаблон для метода: message selector and argument namesСкопируйте шаблон с нашим методом sing поверх этого метода, потом щелкните правой кнопкой мышки на accept. [ex1b] singМетод sing появился в категории методов Singing. Теперь перейдите в рабочее пространство и наберите: Person new sing. Появится bad impression. Вот как это выглядит: Следующий метод, который мы обсуждали был sing:,
он имел один параметр: 'MaryHadALittleLamb'. Теперь вы видите очевидную
трудность нашего первого метода: song и label запрограммированы только
для того, что мы туда поместим. Более разумным будет создать метод,
который знает, что мы поем,
и который сможет получать параметры от различных методов чтобы упростить или использовать
повторно наш код. Таким образом, если вдруг вы захотите скорректировать
процесс воспроизведения пения, придется обновлять гораздо меньше мест.
Давайте создадим новый метод
(помните, что мы называем наши собственные методы, используя префикс 'my'),
который определяет, как мы будем воспроизводить пение на основе того, что поется:
mySing: someLyrics withTitle: aTitleДавайте оптимизируем (refactor) наш первый метод sing чтобы использовать этот закрытый (private) метод. Просто скопируйте его прямо на метод sing или отредактируйте текст, приняв его (accept): [ex1d] singОбратите внимание, текст и название песни все еще явно определены в публичном (public) методе sing, поэтому они недоступны прямо из других объектов и методов Person, но это уже лучше, чем было раньше. Мы рассмотрим лучший способ организации вашего кода, когда будем заниматься следующей песней, и проиллюстрируем, как может быть полезно вынесение текста песни за рамки метода. Имея это в виду, давайте создадим метод lyrics для нашей следующей песни: [ex1e] maryHadALittleLambLyricsТеперь мы можем добавить наш метод sing:, который использует наш закрытый метод mySing:withTitle:. Он достаточно прост и, по умолчанию, имеет значение 'A bad impression of Sinatra', если не понятно, что метод запросили спеть. Важно: когда мы просим спеть aSong, если он равен 'MaryHadALittleLamb', то возвращается булев объект (boolean object). Потом мы определяем значение этого булева объекта, правда он, или ложь. [ex1f] sing: aSongПомните, что вы можете сразу запустить только что добавленный метод, так как не нужно никаких циклов компиляции-связывания-запуска. Наконец, давайте добавим наш последний поющий метод, который похож на метод выше: [ex1g] sing: aSong andDoIt: anAdjectiveЭтот метод использует другой закрытый метод, который строится на нашем первом закрытом методе. Теперь вы видите, как вынесение текстов песен в отдельный метод может быть полезным: вы можете получить к ним доступ когда нужно. Чтобы петь громче используется верхний регистр, тише - нижний регистр. [ex1h] mySing: someLyrics inManner: anAdjective withTitle: aTitleЯ опускаю описание метода whatIsMyHeight, так как он очень похож на то, что мы только что рассмотрели. Обратите внимание на простую условную логику, которую мы использовали здесь. Ее можно избежать программными методами, такими, как двойная доставка (double dispatching), но это выходит за рамки данной статьи. Возможность обойтись без условной логики (conditional logic) обычно считается одним из преимуществ объектно-ориентированного программирования. Чтобы это проиллюстрировать, представьте себе, что у нас есть 30 различных песен, которые нужно спеть. Это заставит нас иметь 30 различных конструкций ifTrue или использовать оператор CASE (большинство версий Smalltalk даже не имеет такого оператора CASE) с 30-ю различными случаями. И если мы захотим добавить еще 5 песен - придется отследить все места, где мы описали предыдущие 30 песен и добавить туда наши дополнительные 5; скорее всего таких мест в программе больше, чем одно, поэтому у вас, вероятно, возникнут проблемы с синхронизацией. Но, для простоты изложения, мы все же используем здесь условную логику. Забегая впередСледующая статья будет посвящена объектно-ориентированному программированию (ООП). К настоящему моменту мы уже рассмотрели кое-какие основы. Я расскажу о преимуществах ООП и различиях между ООП и другими типами программирования.Как пользоваться отладчиком в SqueakВ этой секции я не буду объяснять код программы или примеры, мы попробуем разобраться в кое-чем другом. В этом месяце мы разберемся с отладкой (debugging), так как это то, что я считаю хорошей чертой Smalltalk. Вы можете отлаживать и исправлять ваши программы в реальном времени прямо в отладчике, при этом не нужно никаких циклов компиляции-связывания-запуска.Чтобы проиллюстрировать это, где-нибудь в код aPerson мы вставим сообщение (message) halt. Отредактируйте метод sing: в качестве первой строки поместите self halt. Ваш метод должен выглядеть так, как здесь: [ex2] self halt.
Теперь попросите вашего человека запеть
с помощью такой команды: Person new sing. Вы увидите отладчик:
Щелкните на кнопке Debug и щелкните на 2-ом методе в стеке методов.
Вот как это выглядит:
Теперь удалите self halt., затем
щелкните средней кнопкой мыши и выберите в меню пункт accept
- в этом месте ваш код обновлен так, что любые запросы к методу sing
получают новую версию. Вы можете продолжить выполнение: поместите курсор мышки
над верхней панелью, щелкните средней кнопкой мыши и выберите
пункт меню proceed
Вопросы и ОтветыВ этом месяце вопросов не будет, я полагаю, весь материал из предыдущей статьи был прост и ясен ;-)ГлоссарийЭто глоссарий терминов, которые я использовал в первый раз в этом цикле статей, или терминов, которые я хочу уточнить. Если вы не можете найти обяъснение ккакого-либо термина, упоминавшегося здесь, попробуйте заглянуть сюда.Базовые классы (Base Classes)
Пространство имен (Namespace)
Коллизии пространства имен (Namespace collision)
Рефакторизация (Refactor)
Сноски[1] Файл перепишет, но не удалит, любую существующую структуру/поведение. Например, если у вас в классе есть метод, который не существует в соответствующем классе для подзагрузки (filein), тогда такой метод все еще будет там и после нее. С изменяемыми множествами (change sets) все происходит немножко по-другому, и мы обсудим их в будущих статьях, если вам будет интересно.[2] Технически это не правильно. Как и во многих других частях
этого цикла статей, я все немного упрощаю, чтобы материал был понятен для начинающих.
Давайте будем считать для простоты , что Object является корневым объектом (root object) языка Smalltalk.
|
Copyright © 2001, Jason Steffler. Copying license http://www.linuxgazette.com/copying.html Published in Issue 62 of Linux Gazette, February 2001 |
Вернуться на главную страницу |