![]() |
Третий путь
Я решил пойти по третьему пути: создать коллекцию методов и брать методы из нее.
Это быстрый вариант, понятный большинству разработчиков и в нем можно задействовать константы класса FormatSVG. Хотя без некоторых переделок не обойтись. Опять протестируем на коротком примере. Объявим статической константой коллекцию методов и добавим ссылку на метод: Код AS3:
Мы можем создать такой экземпляр перед объявлением коллекции: Код AS3:
Код AS3:
Код AS3:
Чтобы избежать этого, передадим текущий объект в аргументах и внутри методов будем использовать обращение используя только его. А поскольку пустой экземпляр в таком случае не нужен, удаляем объявление константы INSTANCE и делаем метод createMoveToCommand статическим. Вот что получается: Код AS3:
Мы честно пытались сделать makeDrawCmds лучше и достигли определенных успехов: теперь он читабелен. Но структура кода пока очень жесткая и мы столкнулись с тем, что не можем сделать этот участок лучше. Стоит ли продолжать? Нужно уметь остановиться и сказать себе, что время этой части кода еще не наступило. Позднее, когда архитектура проекта станет лучше, мы вернемся к этому вопросу. |
Рефакторинг метода extractCommands
Переименуем методы: makeDrawCmds в makeDrawCommands и extractCmds в extractCommands.
И перейдем к рефакторингу метода extractCommands. Даже визуально заметно, что метод можно разделить на две части: логику применения атрибутов и разбиение строки запятыми. Начнем со второй части. Создаем метод pathDataToArray и копируем в него логику разбиения строки запятыми: Код AS3:
Код AS3:
|
Рефакторим extractCommands
Вернемся к методу extractCommands.
Он всё еще великоват по размеру и его логика теряется во множестве условных операторов. К тому же метод содержит логически обособленные блоки, которые проще воспринимать отдельными методами. Для начала попробуем вынести блок if (hasFill). В строке, следующей за if (hasFill) добавим: Код AS3:
Далее по очереди проходим по подсвеченым ошибкам и решаем что делать. startColor - объявим локально. node - объявим аргументом функции и передадим node в вызове. thisColor - объявим локально. Далее заменим присвоение переменной fill значения на return. Заодно удалим участки else, поскольку они оказываются ненужными. В итоге получаем такой метод: Код AS3:
Сносим закомментированный код и этот участок кода превращается во вполне удобоваримый: Код AS3:
|
hasStroke
На очереди следующий участок - блок if (hasStroke).
Поступаем аналогично предыдущему случаю и получаем такой метод: Код AS3:
Код AS3:
|
блок hasTransform
Блок кода if (hasTransform) аналогичными действиями превращается в метод:
Код AS3:
Код AS3:
Код AS3:
Рефакторинг в этом смысле очень похож на ситуацию, когда мы берем груду запчастей и начинаем их все раскладывать по полочкам, иногда вытирая пыль. В этом процессе нам достаточно в общем виде представлять зачем запчасть нужна, при этом нас совершенно не заботит как именно она делает свое дело. Процесс рефакторинга не изменяет логику приложения, но, в итоге, дает нам возможность впоследствии сделать это точечно, сосредоточившись на изменении логики небольших методов. Просто сравните каким был метод extractCommands и каким он стал сейчас. В данный момент его логика прозрачна и понятна. Логика каждого из вынесенных методов не требует семи пядей во лбу и может быть легко изменена или оптимизирована, если такая потребность возникнет. |
Необходимость структурных преобразований
Если вы помните, в самом начале мы определяли цели, к которым стремимся в процессе рефакторинга. Мы решили, что целью будет приведение кода в такой вид, при котором он мог бы стать основой для редактора SVG файлов.
Когда я смотрел статьи и спецификацию SVG формата, я обратил внимание на то, что на самом деле наш проект очень далек даже от базовых возможностей формата. К примеру, если у нас будет SVG файл, содержащий окружность, заданную в соответствии со спецификацией, наш код не сможет ее отрисовать. В нашу задачу не входит создавать недостающее, но мы должны сделать всё, для того, чтобы новые классы органично вошли в проект. То что есть сейчас - отрисовка фигуры произвольной формы или пути. И мы знаем, что могут быть другие фигуры. В этой ситуации логично создать специальный пакет, в котором классы этих фигур смогут жить. Второй немаловажный момент - необходимость перехода от представления пути к представлению редактируемой фигуры. Тут понадобятся разъяснения: мы уже понимаем, что происходит: мы получаем строковые данные из атрибута d, разбиваем на конкретные команды в формате svg и преобразуем эти команды в удобоваримые для flash. К сожалению, в некоторых случаях это необратимая операция: кривые Безье третьего порядка, будучи разбитыми на последовательность кривых Безье второго порядка обратно уже не восстановить. А это требуется, поскольку для пользователя условия редактирования объекта не должны ухудшаться. В итоге, систему нужно переводить на другие рельсы: - данные формата должны сохраняться и конвертироваться только на этапе отрисовки; - каждый тип XML узла SVG формата должен иметь соответствующий класс; |
К разработке
Помечаем в мозгу, что рефакторинг остановлен и мы начинаем заниматься разработкой.
Тактика, которую мы будем использовать такова: создаем классы и методы, которые считаем нужными, и с таким интерфейсом, который считаем удобным. Затем используем то, что нам необходимо из старого проекта, но не тупо переносим, а делаем это по аналогии, и с использованием возможностей AS3. Начнем со структуры. В папке svg создадим класс DocumentSVG. В папке geom создадим папку lines и переместим в нее все классы папки geom, исправим ошибки, возникшие вследствие этого. Вернемся к стандарту SVG, а именно к его части, описывающей остальные фигуры: http://www.w3.org/TR/SVG11/shapes.html#Introduction и посмотрим, рисование каких фигур поддерживается: path, rect, circle, ellipse, line, polyline, polygon. Создадим папку shapes в папке geom. Создадим базовый класс для всех фигур: ShapeSVG. И в этой же папке объявим интерфейс IShapeSVG: Код AS3:
ShapeSVG и имплементируем интерфейс IShapeSVG. По-началу все они будут выглядеть как близнеца братья, вот так: Код AS3:
|
театр одного актера! :)
нескромный вопрос из зала: как возможен рефакторинг без тестирования? |
Цитата:
- отсутствие формализованных тестов вовсе не означает, что тестирования нет (ты все-таки статью не читал). - а во-вторых - можно. Представь себе. Особенно в данном случае, когда исходный AS2 код сам не проходит тестов. Мне что, приводить его в порядок и затем портировать? Не стоит клинить на вызубреных догмах из учебников. Делать нужно так, как лежит душа и как подсказывает интуиция. И да, с ответами - в приват. |
| Часовой пояс GMT +4, время: 16:51. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.