Форум: "Потрепаться";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
ВнизОпрос - рефакторинг Найти похожие ветки
← →
КаПиБаРа © (2005-02-03 15:11) [0]Сколько примерно % кода вы пишете сразу на чистовую (т.е. код не нуждается в рефакторинге)?
Сколько в среднем/максимум стадий рефакторинга приходится на функцию/модуль?
← →
Ega23 © (2005-02-03 15:14) [1]Если глобально смотреть - то ~ 20%. ТЗ больно часто меняются... :-(
← →
TUser © (2005-02-03 15:15) [2]0% - в рефакторинге нуждается все. Но не всегда руки доходят.
← →
Юрий Зотов © (2005-02-03 15:16) [3]> КаПиБаРа © (03.02.05 15:11)
1. Примерно сто.
2. Примерно ноль.
При условии, что проектировал тоже сам.
← →
Игорь Шевченко © (2005-02-03 15:19) [4]Вопрос некорректный. Рефакторинг - не самоцель. Любой код пишется начистовую, и, почти любой код нуждается хоть в каком-нибудь, но рефакторинге. Особенно - чужой :)
← →
Ega23 © (2005-02-03 15:21) [5]При условии, что проектировал тоже сам.
Счастливый человек... Есть возможность проектировать самому...
← →
Sergey_Masloff (2005-02-03 15:27) [6]Когда пишу 100% начистую.
Когда пройдет года три - думаешь какой рефакторинг переписать все на фик ;-)
← →
Юрий Зотов © (2005-02-03 15:27) [7]> Игорь Шевченко © (03.02.05 15:19) [4]
> Любой код пишется начистовую...
... и при этом в него заранее закладывается возможность рефакторинга...
:о)
← →
КаПиБаРа © (2005-02-03 15:28) [8]Игорь Шевченко © (03.02.05 15:19) [4]
почти любой код нуждается хоть в каком-нибудь, но рефакторинге
Вопрос в том делаете вы его (рефакторинк кода, который в этом нуждается) или нет? А если не делаете, то почему?
← →
Игорь Шевченко © (2005-02-03 15:43) [9]КаПиБаРа © (03.02.05 15:28) [8]
Делаю, разумеется, если нужно.
А почему делаю - жизнь на месте не стоит.
Юрий Зотов © (03.02.05 15:27) [7]
А что, можно писать иначе ?
С уважением,
← →
Prohodil Mimo © (2005-02-03 15:45) [10]Если заказчик не отклонится от первоначального задания, то никакого рефакторинга и не требуется, но такое довольно редко, обычно некоторые вещи приходится пересматривать.
ЗЫ. ТЗ сам составляю, другим не доверяю.
← →
wicked © (2005-02-03 15:53) [11]> Юрий Зотов © (03.02.05 15:27) [7]
> ... и при этом в него заранее закладывается возможность
> рефакторинга...
если не трудно, можете подсказать, как и какими методами заложить в код возможность рефакторинга?...
← →
msguns © (2005-02-03 16:18) [12]В зависимости от проекта.
Если работа чисто на заказ, то, как правило, правок очень мало. Только если существенно меняется ТЗ (например, структура БД), но это редко, да и сам виноват, на ТЗ "лоханулся"
Если проект "на витрину", в смысле под массовую продажу, то код лижется постоянно, даже когда прога уже "на ходу". Причем не редко, когда переписывается нафиг бОльшая часть кода.
Постановку и ТЗ делаю, как правило, сам.
← →
pasha_golub © (2005-02-03 16:26) [13]msguns © (03.02.05 16:18) [12]
Согласен, про заказ и витрину.
← →
han_malign © (2005-02-03 16:51) [14]>обычно некоторые вещи приходится пересматривать.
- "некоторые вещи" нужно предусматривать... Код нужно планировать гибким и масштабируемым - специально для этого придумывались всякие хитрые декомпозиции(например - модульная, функциональная и ОО). А в Delphi, со ссылками на классы, и С++, с шаблонами - сам Страуструп велел...
>то код лижется постоянно
>Причем не редко, когда переписывается нафиг
- это лечится - по методу ЮЗ и рекомендациям Страуструпа - накоплением базовых библиотек, хорошо структурированного, раз и навсегда вылизанного, с "возможностью повторного использования" кода.("reusable code"(c)Б.Страуструп - с первой до последней редакции, практически через страницу)
← →
Danilka © (2005-02-03 16:57) [15]Серверная часть: вьюхи, процедуры, пакеты и т.д., по мере наполнения данными и добавления новых фич долго живут очень редко. Только самые простые.
← →
Сергей Суровцев © (2005-02-03 17:14) [16]>msguns © (03.02.05 16:18) [12]
Так и есть.
>han_malign © (03.02.05 16:51) [14]
>это лечится - по методу ЮЗ и рекомендациям Страуструпа -
Это все замечательно, если есть МНОГО времени на предварительную подготовку и продумывание проекта и его реализацию, обычно же все упирается в очень жесткие сроки. Но все равно если он для широких масс, возникнет и масса непредвиденных требований. Но по большей части это касается не переписыванием кода как такогого, а заменой блока целиком в момент расширения функционала на вариант более настраиваемый и универсальный.
← →
Antonn © (2005-02-03 17:44) [17]
> Сколько примерно % кода вы пишете сразу на чистовую
> (т.е. код не нуждается в рефакторинге)?
5-10%
> Сколько в среднем/максимум стадий рефакторинга
> приходится на функцию/модуль?
1-3 / максимум не достижим :)
← →
Юрий Зотов © (2005-02-03 18:06) [18]> wicked © (03.02.05 15:53) [11]
Основная идея - структура продукта и его движок должны быть спроектированы универсальными. Так, чтобы их можно было легко наращивать, но никогда не нужно было менять (по крайней мере, менять в принципе).
Как это делается - трудно сказать конкретно, во многом зависит от самого продукта. Основные инструменты - опыт и чутье. Плюс, конечно, структурирование, идеология наследования и полиморфизма (даже если речь не идет об ООП в его чистом виде, то идеи ООП вссе равно могут быть использованы). И т.п.
Тут как-то ветка была про парсинг. И были приведены два кода, решающие одну и ту же задачу. Потом исходная задача расширилась - наряду со старыми потребовалось обрабатывать еще и новые виды данных. Так вот - один код для этого пришлось переписывать, а другой - нет. Потребовалось лишь внести описание этих новых данных в заранее предусмотренные таблицы и заранее предусмотренным способом. В самом же обрабатывающем коде не изменилось ни одного символа - вот это и есть пример того, что рефакторинг был предусмотрен изначально.
← →
wicked © (2005-02-03 18:09) [19]> Юрий Зотов © (03.02.05 18:06) [18]
спасибо...
← →
msguns © (2005-02-03 18:18) [20]>han_malign © (03.02.05 16:51) [14]
>- "некоторые вещи" нужно предусматривать... Код нужно планировать гибким и масштабируемым - специально для этого придумывались всякие хитрые декомпозиции(например - модульная, функциональная и ОО). А в Delphi, со ссылками на классы, и С++, с шаблонами - сам Страуструп велел...
Вашими б устами (или Страуструповскими)
Вы писали что-нибудь из области экономики или бухгалтерии, где было б активно заюзано действующее законодательство ? Если да, то тогда Вы должны себе представлять насколько эта самая деятельность у законодательства может измениться. Причем резко ! Особенно это касается зарплаты и всевозможных отчетов налоговой, пенсионному, ФЗ, соцстраху и хрен еще знает кому (список тоже меняется периодически). Вам знакомы, к примеру, понятия "льготы", "категории льгот", "диффререцированные шкалы" и т.д. ? Вы знаете, что все это может враз поменяться. И фиксированное отчисление стать по шкале, а "шкальные" диффрененцированы по категориям льгот ?
Как ЭТО можно предусмотреть ? Можно, конечно, как в свисте, забомбить формальное описание алгоритмов и переложить свои траблы на плечи (мозги, руки) будных бухгалтеров, но тогда и цена Вашему продукту, ИМХО, невысока.
← →
han_malign © (2005-02-03 18:34) [21]>Можно, конечно, как в свисте, забомбить формальное описание алгоритмов и переложить свои траблы на плечи (мозги, руки) будных бухгалтеров, но тогда и цена Вашему продукту, ИМХО, невысока.
- цена то как раз кусается :).
И если, при, довольно регулярном, изменении "действующего законодательства", Вам приходится делать рефакторинг, и выпускать новую версию - то получается, что за предыдущую версию Вашей программы заплатили зря? Или, все таки, методы внешних (без перекомпиляции ядра) настроек/расширений формальных алгоритмов, имеют право на жизнь?
← →
Юрий Зотов © (2005-02-03 18:52) [22]> msguns © (03.02.05 18:18) [20]
> Как ЭТО можно предусмотреть?
А давайте рассмотрим три программы, построенные по таким схемам:
1. код - данные
2. код - описание_данных - данные
3. код - описание_алгоритма - описание_данных - данные
В первой программе код и заложенный в нем единственный алгоритм жестко привязаны к определенной структуре данных - поэтому код придется переписывать (и отлаживать!) всякий раз, как только меняется либо структура данных, либо алгоритм их обработки. Получаем - каждому клиенту нужна своя программа (потому что у разных клиентов разные структуры данных и разные алгоритмы их обработки), а при изменении законодательства (что тоже означает изменение структуры данных и алгоритма их обработки) каждую из этих программ придется переписывать (поддержка клиентов).
Вторую программу при изменении структуры данных переписывать уже не придется - нужно будет только модернизировать описание данных, а дальше код будет его использовать и сможет работать с новыми данными без своей переделки. Но при изменении алгоритма обработки код тоже придется переписывать (и тоже по новой отлаживать). В смысле трудоемкости адаптации под разных клиентов и трудоемкости их поддержки это уже гораздо лучше, но тоже еще не идеал.
Наконец, код третьей программы переписывать уже не придется. Все клиенты всегда и при любом законодательстве имеют одну и ту же программу, а при необходимости (для другого клиента, дибо при смене законодательства) меняется лишь ее описательная часть.
Пусть каждая из этих трех программ выпускается отдельной фирмой. Учитывая, что самая длительная, трудоемкая и дорогостоящая вещь - это разработка, отладка и сопровождение самого кода, скажите - какая фирма в конечном счете окажется успешнее других? При допущении, что уровень маркетинга во всех трех одинаков (поскольку маркетинг - это уже другой вопрос).
← →
Сергей Суровцев © (2005-02-03 19:04) [23]>Юрий Зотов © (03.02.05 18:06) [18]
>han_malign © (03.02.05 18:34) [21]
Ядро - это конечно хорошо. Но это как раз та область, которую можно и долго-хорошо проектировать и аккуратно-спокойно реализовывать. А все проблемы начинаются там, где времени мало, а подходы меняются. В случае разделения системы на ядро и скрипты вся тяжесть рефакторинга просто уходит в скриптовую часть.
← →
Сергей Суровцев © (2005-02-03 19:23) [24]>Юрий Зотов © (03.02.05 18:52) [22]
Юрий, я охотно верю, что именно Ваша часть кода в рефакторинге практически не нуждается. Но спросите свой отдел внедрения, какая ситуация у них, и могут ли они себе позволить долго создавать универсальные решения в тот момент, когда нужны пусть жесткие, но быстрые.
>Наконец, код третьей программы переписывать уже не придется.
>Все клиенты всегда и при любом законодательстве имеют одну и ту
>же программу, а при необходимости (для другого клиента, дибо
>при смене законодательства) меняется лишь ее описательная часть.
Здесь Вы опять говорите о своей части работы. Описательная часть - это скрипты, реализованные внедренцами и обрабатываемые с помощью ядра. Ядро менять не придется, но скрипты обязательно и часто. А ведь программа - это все вместе, отдельно одно от другого никому не нужно.
← →
Сергей Суровцев © (2005-02-03 19:38) [25]>han_malign © (03.02.05 18:34) [21]
>И если, при, довольно регулярном, изменении "действующего
>законодательства", Вам приходится делать рефакторинг, и
>выпускать новую версию - то получается, что за предыдущую
>версию Вашей программы заплатили зря? Или, все таки, методы
>внешних (без перекомпиляции ядра) настроек/расширений
>формальных алгоритмов, имеют право на жизнь?
Очевидно Win XP из Win 3.11 Вы получили без перекомпиляции ядра, а путем установки внешних настроек? Или же зря платили за все промежуточные версии.
← →
Jeer © (2005-02-03 19:47) [26]Мда..
Который раз вспоминаю ту нимфу, которая уберегла меня от коллективной работы, после того как последняя мне надоела навзничь:)
Рефакторинг закладывается на этапе проектирования и складывается из вполне разделимых составляющих.
Ю.З тут не одинок:)))
Системная идея - Алгоритмы - Данные - Визуализация - Инструментарий
Не буду уточнять подчиненность(разветвленность) приведенного спуска.
← →
Marser © (2005-02-03 20:26) [27]
> Игорь Шевченко © (03.02.05 15:19) [4]
> Вопрос некорректный. Рефакторинг - не самоцель. Любой код
> пишется начистовую, и, почти любой код нуждается хоть в
> каком-нибудь, но рефакторинге. Особенно - чужой :)
Amen
← →
Юрий Зотов © (2005-02-03 20:35) [28]> Сергей Суровцев © (03.02.05 19:23) [24]
> Но спросите свой отдел внедрения, какая ситуация у них, и
> могут ли они себе позволить долго создавать универсальные
> решения в тот момент, когда нужны пусть жесткие, но быстрые.
Я в курсе, так что можно и не спрашивать...
:о)
Понимаете, вот эта схема разбиения на униврсальные и неуниверсальные куски - она же применима не только ко всему проекту в целом, но и к отдельным его частям тоже. И когда мы применяем ее к маленьким кускам, то оказывается, что на ее реализацию требуется почти то же самое время, что и на "жесткое" решение. Поскольку сам кусок-то невелик.
Зато на следующее внедрение уже требуется меньшее время, потому что используются прежние наработки. А если еще учесть, что "следующих" внедрений много, то в итоге получаем снижение, а не увеличение сроков, трудозатрат, да и стоимости тоже.
Конкретно - в августе 93-го я вернулся в софтверную контору, из которой уходил за два года до этого. Вернулся на должность технического директора - то есть, человека, который рулит и проектом, и производством, и его технологией.
И обнаружил плачевную картину - чуть ли не каждый наш клиент имел собственную версию программы. Внедренцы и поддержка просто задыхались в этой неразберихе и в объеме работы. Не говоря уже о невозможности развития проекта и самой конторы - ведь из-за этого набирать новых клиентов мы уже просто практически не могли, а программисты занимались, в основном, правкой багов (а как им не быть при такой-то постановке дела?).
Сразу же начал, как мог, бороться с этой фигней. В том числе, используя то, о чем мы говорим. Результат - сейчас мы имеем ОДНУ программу и не особо большие отличия в БД для ВСЕХ клиентов, за счет этого сократили внедрение и поддержку, несмотря на это набрали несколько новых клиентов, внедрили в проект несколько новых фич и повысили его качество. Через годик планирую выпустить версию с новой цифрой в мажоре - и по сравнению с тем, что было, это будет уже СОВСЕМ другой продукт.
Вот что имею сообщить по поводу наших внедренцев. Им стало лучше. И не только им.
:о)
← →
Mystic © (2005-02-03 21:02) [29]Для меня рефакторинг это стиль программирования. Стараюсь двигаться вперед небольшими, но закончеными версиями. Иногда принимаются ошибочные решения, что приводит к рефакторингу.
← →
Юрий Зотов © (2005-02-03 22:01) [30]> ...в августе 93-го...
Блин, 2003-го, конечно. За 12 лет эти результаты можно было бы считать пренебрежимо малыми, а за 1.5 года - вполне неплохо.
:о)
← →
esu © (2005-02-03 22:20) [31]
> Юрий Зотов © (03.02.05 20:35) [28]
А что за программа если не секрет ? Или хотя бы в какой области применения.
← →
y-soft © (2005-02-03 22:35) [32]Всегда проектирую приложения так, чтобы при изменениях в задаче можно было обойтись переделкой небольших модулей. То, что меняется чаще всего, вообще изначально выношу в отдельные плагины, библиотеки и т.п. - иначе никакого здоровья не хватит :), да и для командной работы удобнее...
Насчет того, какая часть кода пишется сразу "начисто" - где-то 95% (оставшиеся 5% - шлифовка и вылизывание мелких деталей, но это уже скорее черта характера :) )
← →
Юрий Зотов © (2005-02-03 22:39) [33]> esu © (03.02.05 22:20) [31]
ERP. Писал уже, повторяться не стоит, а то сочтут за рекламу.
Подробности тут: http://www.elprise.ru
> All
Это правда не реклама, чес-слово. Просто использую те примеры, с которыми хорошо знаком.
← →
iZEN © (2005-02-03 23:00) [34]/**КаПиБаРа © (03.02.05 15:11)
Сколько примерно % кода вы пишете сразу на чистовую (т.е. код не нуждается в рефакторинге)?
Сколько в среднем/максимум стадий рефакторинга приходится на функцию/модуль?
*/
1. Нисколько. Весь код "грязный".
2. Зависит от достижимости целей. Цель достигнута на данном этапе - код оставляется в "покое", цель меняется - меняется код.
P.S. А что Вы лично понимаете под "рефакторингом"? У меня создаётся смутное ощущение, что немного не то Вы понимате, говоря о "стадиях". От стадии к стадии обычно функциональность кода не меняется, но меняются характеристики: повторное использование и надёжность. Защита улучшается, а прямая ыункциональность - нет. Всё остальное делается на этапах анализа ТЗ и проектирования.
← →
iZEN © (2005-02-03 23:01) [35]/**КаПиБаРа © (03.02.05 15:11)
Сколько примерно % кода вы пишете сразу на чистовую (т.е. код не нуждается в рефакторинге)?
Сколько в среднем/максимум стадий рефакторинга приходится на функцию/модуль?
*/
1. Нисколько. Весь код "грязный".
2. Зависит от достижимости целей. Цель достигнута на данном этапе - код оставляется в "покое", цель меняется - меняется код.
P.S. А что Вы лично понимаете под "рефакторингом"? У меня создаётся смутное ощущение, что немного не то Вы понимате, говоря о "стадиях". От стадии к стадии обычно функциональность кода не меняется, но меняются характеристики: повторное использование и надёжность. Защита улучшается, а прямая функциональность - нет. Всё остальное делается на этапах анализа ТЗ и проектирования.
← →
iZEN © (2005-02-03 23:02) [36]опс. прошу прощения за дубль.
← →
Сергей Суровцев © (2005-02-03 23:23) [37]>Юрий Зотов © (03.02.05 20:35) [28]
>Вот что имею сообщить по поводу наших внедренцев. Им стало
>лучше. И не только им.
Да я и не сомневаюсь, что стало лучше. Сам через многое из описанного проходил. И насчет напинания общих моделей тоже согласен. Но как не старайся, но у внедренцев никогда не будет Вашего соотношения ~100/~0. А в самом лучшем случае 80/20 на однотипных объектах.
И зря стесняетесь рекламы. Всегда интересно, что делают коллеги, особенно когда есть на что посмотреть.
← →
Юрий Зотов © (2005-02-03 23:42) [38]> Сергей Суровцев © (03.02.05 23:23) [37]
> в самом лучшем случае 80/20 на однотипных объектах.
Видимо, да. Работа у них такая, у внедренцев - все нужно вчера.
Но движок надо стараться делать 100/0. Иначе внедренцы и поддержка совсем загнутся. А с ними и продукт и, вполне возможно, сама контора.
← →
Petr V. Abramov © (2005-02-04 03:47) [39]> Юрий Зотов ©
> Но движок надо стараться делать 100/0
Насчет 100 - да с тобой спорить себе дороже будет :))
Насчет по нулям - ню-ню :) Но к этому ню-ню надо стремиться. без смайлика.
просто если рефакторинг не требуется - либо сделано фундаментальное открытие в области проектирования/технологии ( и р.ф не нужен до следующего фундаментального открытия), либо проект не развивается, а доживает ( хотя доживать можно долго и с кайфом, питерские программеры всуе не поминаются :)))
← →
Danilka © (2005-02-04 07:52) [40][22] Юрий Зотов © (03.02.05 18:52)
> А давайте рассмотрим три программы, построенные по таким
> схемам:
> 1. код - данные
> 2. код - описание_данных - данные
> 3. код - описание_алгоритма - описание_данных - данные
Ну, вообще-то во всех трех схемах придется затрачивать время на доработку. :)
Хотя, конечно, доработка серверной части, намного легче и проще для установки клиентам, чем каждый раз в паскале ковыряться и рассылать бпл-ки.
Правда, все это как-бы и не рефакторинг, а развитие..
← →
КаПиБаРа © (2005-02-04 08:32) [41]iZEN © (03.02.05 23:01) [35]
что Вы лично понимаете под "рефакторингом"?
Ну эта как бы объяснить... :)
Нужно хранить список выбраных записей.
Был у меня массив. Заменил я его на TList. Сейчас думаю заменить его на TMyList основанный на динамическом массиве или связном списке.
Вот.
← →
Юрий Зотов © (2005-02-04 08:56) [42]> КаПиБаРа © (04.02.05 08:32) [41]
> Сейчас думаю заменить его на TMyList основанный на
> динамическом массиве или связном списке.
А завтра возникнет необходимость использовать этот класс в многопоточном приложении. И либо нарвемся на чудеса, либо придется его переделывать, либо его СРАЗУ надо писать с учетом многопоточности.
Я бы предпочел третий вариант. И подумал о наследовании от TThreadList. А в результате получил бы что-то близкое к 100/0.
← →
jack128 © (2005-02-04 09:04) [43]iZEN © (03.02.05 23:01) [35]
А что Вы лично понимаете под "рефакторингом"?
Рефакторинг представляет собой такого измнения программной системы, при которорм не меняется внешнее поведение кода, но улудшается его внутренняя структура. (с) М. Фаулер
В связи с таким определением вопрос к Юре Зотову
Юрий Зотов © (03.02.05 18:06) [18]
Тут как-то ветка была про парсинг. Угу, помним
Потребовалось лишь внести описание этих новых данных в заранее предусмотренные таблицы и заранее предусмотренным способом. В самом же обрабатывающем коде не изменилось ни одного символа - вот это и есть пример того, что рефакторинг был предусмотрен изначально.
Смотрю на определение Фаулера. Смотрю на тот код. Чесно говоря, не вижу где там предусмотрено зарание возможность улудшения структуры кода. Зато отлично виден потенциал для расширения функционала. Я немного слепой, или просто мы по разному понимает термин рефакторинг??
КаПиБаРа © (04.02.05 8:32) [41]
Сейчас думаю заменить его на TMyList основанный на динамическом массиве или связном списке.
Это не рефакторинг, имхо.
← →
Юрий Зотов © (2005-02-04 09:13) [44]> jack128 © (04.02.05 09:04) [43]
> Я немного слепой, или просто мы по разному понимает термин
> рефакторинг?
Второе. Я предпочитаю трактовать его более общно и менее формально, чем Фаулер. Хотя с точки зрения теории и методологии это, видимо, и не совсем верно, но Фаулер писал книгу, а я пишу программы. Отсюда и разница.
← →
КаПиБаРа © (2005-02-04 09:31) [45]Юрий Зотов © (04.02.05 8:56) [42]
Пока не дорос до такого подхода, когда видно в деталях развитие программы на много шагов вперед. Я пока в рассмотрении пользуюсь абстрактными понятиями объект, связи, свойства и т.д. Могу представить взаимодействие основных объектов и как оно может развиваться, чем быть ограничено, но предвидеть судьбу второстепенного списка созданного для хранения выделенных элементов в одном из списков как то сразу не могу. Реализовал его в виде массива. Потом с окаказоль что хорошо бы сохранять список выделенных элементов в файл. Вот уже и класс можно сделать, хотя и массив можно оставить. Но тогда код обслуживающий сам массив будет по всему модулю размазан, что не есть хорошо.
jack128 © (04.02.05 9:04) [43]
Это не рефакторинг, имхо.
Массив или список являются внутреней структурой кода, рефакторинг которого я делаю. TMyList не является необходимой частью программы он нужен лишь для улучшения структуры "необходимого" кода, т.е. того кода который реализует требуемый функционал.
← →
iZEN © (2005-02-04 10:07) [46]/**К jack128 © (04.02.05 09:04) [43]
>КаПиБаРа © (04.02.05 8:32) [41]
>Сейчас думаю заменить его на TMyList основанный на динамическом массиве или связном списке.
Это не рефакторинг, имхо.
*/
Это-то как раз рефакторинг.
Другой пример: меняем ArrayList на LinkedList - в десятки раз увеличивается быстродейсвтие на операциях вставки/удаления, но, правда во столько же раз уменьшается скорость доступа к элементам, а вот интерфейс доступа - тот же.
Страницы: 1 2 вся ветка
Форум: "Потрепаться";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.044 c