Hello, Maxim! You wrote to Alexander Derazhne on Fri, 25 Mar 2005 13:34:28 +0300:
MP> 1) Какой смысл для интерпретации алгоритма работы ПО имеют записи MP> экстернов и прототипов? (это в наше то время, когда ограничение на MP> объем текстов в 64к проглатываемых редакторами прошло 5 лет назад).
А причём тут "объём проглатываемый редакторами"? Раздельная компиляция придумана не только и не столько для утаптывания процесса редактирования в меньший объём памяти. Главное ключевое слово - декомпозиция. Можно (и ведь приходится!) разбивать задачу на отдельные компоненты, которые будут создаваться и сопровождаться разными людьми. Можно повторно использовать оные компоненты. Можно слинковать свежесозданный компонент с отдельной запускалкой и проверить исключительно его перед тем как отдавать в работу. Если разработка многоуровневая, то можно не отдавать на сторону исходники, а только объектники и хидеры. Можно контролировать внесение изменений. И т.д. Повторяю - это для средних и больших проектов.
Что касается интерпретации человеком, то намного удобней не видеть подробностей реализации того, что тебя в данный момент не интересует. Вот, кстати, пример. В IBM'овском VisualAge for JAVA код структурируется как Project->Package->Class->Member. Но в SUN'овской спецификации рассматриваются только средние два уровня. И каждый класс должен целиком располагаться в одном файле. В результате все остальные редакторы и IDE вводят уровень Project (а иногда ещё и Workspace), но весь текст класса идёт одним куском. И хотя список членов доступен и быстрая навигация возможна - но как же это неудобно! Ну не хочу я постоянно прокручивать банальные аксессоры и конструкторы! Они уже написаны (или вообще сгенерированы) и более не интересны. В С/С++/ASM есть возможность вынести всё нетривиальное в отдельные файлы "и это правильно".
MP> 2) Hайди пример АК - преобразования строки null terminated, в строку MP> со счетчиком. Hайди в нем ошибку. Опиши типичное проявление этой MP> ошибки в проекте. Hа этом примере объясни - как икапсулированность MP> данной функции упростит отладку ДАHHОЙ КОHКРЕТHОЙ ОШИБКИ ?
Ну, эту методичку ты предложишь кому-нибудь другому :-), а я приведу тебе реальный пример. В некотором :-) проекте злостно нарушены правила инкапсуляции. В частности: при поступлении команды "createChannel" функция, занимающаяся разбором команд вызывает один из "конструкторов" (код на чистом С). В конструкторах запрашивается память, строятся структуры данных, запрашивается ещё память и т.д. Но при поступлении команды "destroyChannel" или "setChannelOptions_X" (таких команд на самом деле воз и маленькая тележка) этот парсер может вызвать соответствующую типу канала процедуру, но часто занимается этим грязным делом сам (вот оно, нарушение). А опции _могут_ потребовать замены структур, буферов и т.д. Теперь представь себе, каково мне искать потенциальную утечку памяти, если работа с каналом определённого типа размазана тонким слоем по куче общих мест (парсер только одно из таких мест), а написано всё "с экономией", т.е. если можно объеденить обработку разных типов каналов, команд и пр. в один, перегруженный if'ами кусок кода, то это и делается. Ну, а теперь вообрази, что приходит Заказчик, и говорит: "Мне каналы типов А и Б не нужны - они устарели, тип В у нас не сертифицирован, так что вы их уберите, зато реализуйте мне вместо них новейшие типы Э, Ю и Я". Сколько крови будет стоить повыкусывать всех блох и _убрать_ из кода обработку этих А, Б и В?! Вот что значит не соблюдать декомпозицию и инкапсуляцию...
With best regards, Alexander Derazhne