Может показаться странным, что в обзоре стилей мы специально не выделили
Именно это требование обычно трактуется как модульность программного изделия. Преимущества модульности, понимаемой в общем смысле это возможности замены модуля без изменения всего остального и повторного использования программных фрагментов. Последнее уже можно рассматривать как особый стиль программирования, для которого модульность является одним из средств.
Средства поддержки модульности характеризуют даже не стиль, а конкретный язык, поддерживающий этот стиль. Поэтому правомерно говорить не о стиле, а о конкретном языке, в какой мере он поддерживает модульное построение программ в рамках своего стиля.
Стиль от переиспользования характеризуется тем, что при составлении программы стремятся максимально использовать то, что уже сделано - самим программистом, его коллегами или же вообще где-либо. Давно уже общепризнано, что в идеале на смену программированию как кодированию алгоритмов должно прийти программирование как сборка из заранее заготовленных блоков -
Тем не менее интересно проделать следующий мысленный эксперимент: а что было бы, если математики работали бы примерно в таких же условиях, как программисты?
Ну, ясно, что если бы математик, опубликовавший теорему, брал бы деньги (а тем более требовал бы их заранее) за каждое ее использование, то переиспользование сразу бы си-и-ильно сократилось.
Даже если бы он не брал деньги за теорему саму по себе, но засекретил бы ее доказательство и угрожал бы уголовным преследованием всякому, кто осмелится понять (`дизассемблировать') написанный им текст, ситуация пришла бы к той же мертвой точке (здесь эта калька английского слова `
Видимо, достаточно было бы оплачивать труд математиков на повременной основе, проверяя обоснованность отчетов о затраченном времени по числу строк написанного доказательного текста. Это, может быть, не прекратило бы переиспользование полностью, но любой математик (а не только жулики) при каждом удобном случае переписывал бы чужие доказательства своими терминами и с маленькими изменениями. Здесь к мертвой точке пришли бы медленнее, но столь же неизбежно.
Как видите, мы можем сделать важный социальный и практический вывод: .
Понятно, что при использовании готовых строительных блоков возможны потери. Тем не менее потенциальная выгода за счет переиспользования просто колоссальна. В математике, где имеются точные оценки, показано, что длину доказательства (читай - программы) можно сократить в БАШНЮ ЭКСПОНЕНТ РАЗ без существенной потери эффективности лишь за счет введения
Рассмотрим две реальные ситуации, которые демонстрируют разработку, не ориентированную и ориентированную на переиспользование. В первой ситуации действует программист, работающий с очень развитой системой, в которой есть все. Тем не менее он пишет свою процедуру лексикографического упорядочивания строк, потому что "легче самому написать, чем найти, а потом ведь еще и подгонять придется". Вывод: во-первых, здесь начисто отсутствует стремление к переиспользованию, а во-вторых, переиспользованию могут препятствовать затруднения поиска того, что требуется включить в составляемую программу, а также проблемы совместимости версий.
Вторая ситуация - другая крайность. Программисту на Java потребовалось построить синтаксический анализ. На вопрос о том, как он это делает, получен ответ: "Зачем это знать? У меня есть пакет JavaCC, который все делает, как надо!" Вместе с тем, дальнейшие расспросы показали, что этот программист не представляет себе даже того, какого типа метод анализа поддерживает JavaCC, и, следовательно, ничего не может сказать о том, как задание грамматики для данного пакета связано с эффективностью анализа. Узнав возможные варианты, программист призадумался, но ничего менять не стал. Почему? Ответ простой: "Так ведь все уже работает!" Короче говоря, качество использования готовых компонентов системы зависит от знания о них.
Ситуация опять-таки та же самая, что в математике, особенно в прикладной. Квалифицированное использование теоретических результатов требует знания соответствующей теории, а порою и идей доказательств результатов (поскольку в реальной ситуации предположения теории никогда не выполняются точно). Глубина требуемого знания различна: иногда достаточно общего представления, как, например, при использовании математических функций, иногда нужны сведения о принципах реализации, но всегда можно указать необходимый уровень знакомства с переиспользуемым.
Сравнение ситуаций показывает, что одних пожеланий и директивных указаний для переиспользования мало. Необходимы знания о том, что можно воспользоваться переносимыми компонентами и как именно. Получение же знаний часто требует существенных трудозатрат. Нужно, чтобы само переиспользуемое программное обеспечение было приспособлено для этого, в частности, чтобы оно следовало накопленной в математике хорошей практике, а не игнорировало ее как чистую теорию.
Расшифровка предыдущего предложения позволит вдумчивому читателю самому вывести все условия, необходимые для обеспечения переиспользования в конкретной обстановке. Любые указания здесь бесполезны (если человек еще не осознал предыдущее) либо вредны (если он думает, что осознал, на самом деле ничего не понимая). Можно дать лишь общий совет для тех, кто еще занимается (само)образованием.
В математике для программиста важны не столько конкретные результаты (за ними можно обратиться и к справочной литературе), сколько структура понятий и доказательств, способы введения абстракций и применения исключительно абстрактных понятий в частных ситуациях.
Иногда переиспользованию способствует применение развитых языковых средств. В частности, C++ и Java довольно часто позволяют переносить программы из одной операционной обстановки в другую (перенос - одна из форм переиспользования). Но те, кто реально занимался переносом программ, наверняка вспомнят при чтении предыдущего предложения досадные несоответствия, выявлению и предупреждению которых C++ и Java никак не помогают.
Переиспользованию способствует повышение уровня понятий языка, хотя бы до второго-третьего типа (объектная ориентированность языка). Иногда ООП помогает также возможностями наследования свойств и методов объектов (но часто в самых критических ситуациях плохо продуманная концепция наследования столь же сильно и мешает).
Все это - зародыши поддержки стиля программирования, нацеленного на переиспользование. Но в основном сложившаяся практика в значительной степени препятствует переиспользованию, а уровень систем поддержки еще недостаточно высок и неадекватен общей задаче применения данного стиля.
Переиспользование зависит также от общего уровня знаний и умений программиста (тот, кто способен подняться до уровня метода, склонен к переиспользованию, а тот, кто не может подняться выше тактического планирования, обычно избегает его).
Если ограничиться деятельностью программиста, то, прежде всего, нужно указать на два аспекта данного стиля: применение существующих компонентов и разработка переиспользуемых компонентов.
Применение переиспользуемых компонентов характеризуется следующими особенностями стиля:
При разработке переиспользуемых компонентов необходимо учитывать, что подобная разработка всегда требует дополнительных затрат, которые связаны со следующими требованиями:
В характеристиках обоих аспектов программирования от переиспользования нет явного упоминания специфики традиционных моделей вычислений. Поэтому они не зависят от стиля, в котором написаны компоненты, и в значительной степени от особенностей вычислительных систем, на которых они
Рассмотрим ранее представленные стили с точки зрения их приспособленности к сочетанию со стилем переиспользования.
Во-первых, если фрагмент может быть выделен как черный ящик, т. е. нас интересует лишь соотношение между его входными и выходными данными, то он на уровне программы может рассматриваться как самостоятельный узел переработки данных и тем самым получает независимость от состояний программы. В свою очередь, именно это позволяет использовать такой фрагмент, как самостоятельный узел переработки другой программы - переиспользовать его. На этом принципе строятся все библиотечные математические функции, реализацию которых достаточно часто не требуется даже знать при использовании.
Обычными единицами переиспользования при любом стиле программирования являются процедуры. Именно они автономно описываются, и если оказываются независимыми от общего с другими компонентами контекста, то, по сути дела, становятся теми самыми черными ящиками, о которых только что шла речь.
Еще один возможный случай, когда часть, ясно осознанная программистом, состояний внешней программы может быть интерпретирована как гомоморфный образ части (опять же, явно выделенной) состояний компонента (
Как ни странно, немногим лучше приспособлено к сочетанию со стилем переиспользования структурное программирование. Требования к структуре информационного пространства задачи и к согласованию с ним других компонентов программы обеспечивают регламентированные связи между подзадачами, а значит, облегчается (но не исчезает) задача выделения самостоятельных компонентов. В дополнение к полностью самостоятельным переиспользуемым компонентам здесь можно указать на переиспользование, при котором в новом применении обеспечивается необходимая часть контекста (т. е. переиспользуются компонент и эта часть контекста; смотри модули языков Modula-2 и Object Pascal ). Модули можно рассматривать как
Следует отметить, что для рассмотренных случаев задача переиспользования достаточно часто требует модификации того, что предоставляется. Рассмотрим простейший пример, который не выходит за рамки переиспользования черного ящика. Функция вычисления квадратного корня определена только для неотрицательных аргументов. Вопрос: нужна ли в переиспользуемой подпрограмме вычисления этой функции проверка? С одной стороны, она повышает надежность программирования, но с другой - оказывается избыточной, когда точно известно (можно доказать), что аргумент больше нуля. В рамках традиционной техники простых механизмов отключения проверки быть не может, поскольку все они нарушают принцип черного ящика. В
Внимание!
Многовариантность как форма
При использовании сентенциального стиля возможности перестройки переиспользуемого компонента под ситуацию гораздо выше за счет высокоуровневых принципов вычислений. Однако точных практических оценок этого пока что нет. Как правило, повторно используются крупные и содержательно полные фрагменты программ, чаще всего именно те, которые являют собой базовые механизмы, развивающие
Но неимперативность по своей сути лучше приспособлена для переиспользования и, в частности, для шаблонного переиспользования, поскольку соотношения вместо приказов легче автоматически трансформировать или даже просто переинтерпретировать в другой обстановке (отсутствие императивности - еще один фактор, обусловливающий уже не раз упоминавшуюся практически абсолютную переносимость математических результатов). Неудивительно, например, что базы данных-фактов в программах на языке Prolog часто становятся их общими частями.
В событийном программировании заранее предписана декомпозиция программы: выделение в ней уровней генерации событий и их обработки. Уже само это наталкивает на мысль осуществимости общего генератора для однотипных программ. Нельзя забывать и о том, что событийный механизм или управление с помощью приоритетов неизбежно повышает автономность обработчиков: например, они могут не обязательно рассчитывать на определенную последовательность вызовов, и, как следствие, их гибкость повышается.
Сегодня наиболее отлаженными с точки зрения переиспользования являются программы в объектно-ориентированном и в функциональном стиле. Общая причина тому - гибкие средства абстракции соответствующих языков и четкое отделение интерфейсов от реализаций. Это повышает потенциальные и реальные возможности переиспользования. Вместе с тем, скажем, объектно-ориентированный стиль эффективен лишь для достаточно больших систем и тем самым вдохновляет программистов на построение больших систем классов и объектов, которые сильно взаимосвязаны. А это, в свою очередь, заставляет технологизировать разработки. Технология в настоящее время связывается с наработкой типовых моделей фрагментов объектно-ориентированных систем. Создаются
Проектирование с учетом повторного использования результатов в будущем возможно осуществлять на четырех уровнях.
Приведенный перечень упорядочен по степени значимости уровней для переиспользования. Наибольшая эффективность достигается, когда удается при проектировании выйти на уровень решений, но одновременно этот уровень является наиболее сложным и трудоемким для разработки.
В заключение отметим, что условия применения стиля от переиспользования в реальном программировании должны включать в себя оценку как экономических показателей, так и уровня квалификации исполнителей. А это уже функции менеджера проекта, который должен решать, ориентироваться ли на переиспользование (в обоих аспектах) или нет, и если да, то решить многие финансовые и организационные проблемы, выходящие за рамки собственно программирования.
Предупреждение!
Здесь необходима трезвая оценка уровня своих специалистов и организованности работ, поскольку на действительно выгодное для переиспользования решение способны, как правило, лишь высококвалифицированные специалисты в хорошей инфраструктуре.
Программирование от
Не всякое переиспользование уместно считать программированием от
Можно указать следующие характерные случаи применения программирования от
Использование технологического и технического
Стиль программирования от
Может показаться странным, что в обзоре стилей мы специально не выделили
Именно это требование обычно трактуется как модульность программного изделия. Преимущества модульности, понимаемой в общем смысле это возможности замены модуля без изменения всего остального и повторного использования программных фрагментов. Последнее уже можно рассматривать как особый стиль программирования, для которого модульность является одним из средств.
Средства поддержки модульности характеризуют даже не стиль, а конкретный язык, поддерживающий этот стиль. Поэтому правомерно говорить не о стиле, а о конкретном языке, в какой мере он поддерживает модульное построение программ в рамках своего стиля.
Стиль от переиспользования характеризуется тем, что при составлении программы стремятся максимально использовать то, что уже сделано - самим программистом, его коллегами или же вообще где-либо. Давно уже общепризнано, что в идеале на смену программированию как кодированию алгоритмов должно прийти программирование как сборка из заранее заготовленных блоков -
Тем не менее интересно проделать следующий мысленный эксперимент: а что было бы, если математики работали бы примерно в таких же условиях, как программисты?
Ну, ясно, что если бы математик, опубликовавший теорему, брал бы деньги (а тем более требовал бы их заранее) за каждое ее использование, то переиспользование сразу бы си-и-ильно сократилось.
Даже если бы он не брал деньги за теорему саму по себе, но засекретил бы ее доказательство и угрожал бы уголовным преследованием всякому, кто осмелится понять (`дизассемблировать') написанный им текст, ситуация пришла бы к той же мертвой точке (здесь эта калька английского слова `
Видимо, достаточно было бы оплачивать труд математиков на повременной основе, проверяя обоснованность отчетов о затраченном времени по числу строк написанного доказательного текста. Это, может быть, не прекратило бы переиспользование полностью, но любой математик (а не только жулики) при каждом удобном случае переписывал бы чужие доказательства своими терминами и с маленькими изменениями. Здесь к мертвой точке пришли бы медленнее, но столь же неизбежно.
Как видите, мы можем сделать важный социальный и практический вывод: .
Понятно, что при использовании готовых строительных блоков возможны потери. Тем не менее потенциальная выгода за счет переиспользования просто колоссальна. В математике, где имеются точные оценки, показано, что длину доказательства (читай - программы) можно сократить в БАШНЮ ЭКСПОНЕНТ РАЗ без существенной потери эффективности лишь за счет введения
Рассмотрим две реальные ситуации, которые демонстрируют разработку, не ориентированную и ориентированную на переиспользование. В первой ситуации действует программист, работающий с очень развитой системой, в которой есть все. Тем не менее он пишет свою процедуру лексикографического упорядочивания строк, потому что "легче самому написать, чем найти, а потом ведь еще и подгонять придется". Вывод: во-первых, здесь начисто отсутствует стремление к переиспользованию, а во-вторых, переиспользованию могут препятствовать затруднения поиска того, что требуется включить в составляемую программу, а также проблемы совместимости версий.
Вторая ситуация - другая крайность. Программисту на Java потребовалось построить синтаксический анализ. На вопрос о том, как он это делает, получен ответ: "Зачем это знать? У меня есть пакет JavaCC, который все делает, как надо!" Вместе с тем, дальнейшие расспросы показали, что этот программист не представляет себе даже того, какого типа метод анализа поддерживает JavaCC, и, следовательно, ничего не может сказать о том, как задание грамматики для данного пакета связано с эффективностью анализа. Узнав возможные варианты, программист призадумался, но ничего менять не стал. Почему? Ответ простой: "Так ведь все уже работает!" Короче говоря, качество использования готовых компонентов системы зависит от знания о них.
Ситуация опять-таки та же самая, что в математике, особенно в прикладной. Квалифицированное использование теоретических результатов требует знания соответствующей теории, а порою и идей доказательств результатов (поскольку в реальной ситуации предположения теории никогда не выполняются точно). Глубина требуемого знания различна: иногда достаточно общего представления, как, например, при использовании математических функций, иногда нужны сведения о принципах реализации, но всегда можно указать необходимый уровень знакомства с переиспользуемым.
Сравнение ситуаций показывает, что одних пожеланий и директивных указаний для переиспользования мало. Необходимы знания о том, что можно воспользоваться переносимыми компонентами и как именно. Получение же знаний часто требует существенных трудозатрат. Нужно, чтобы само переиспользуемое программное обеспечение было приспособлено для этого, в частности, чтобы оно следовало накопленной в математике хорошей практике, а не игнорировало ее как чистую теорию.
Расшифровка предыдущего предложения позволит вдумчивому читателю самому вывести все условия, необходимые для обеспечения переиспользования в конкретной обстановке. Любые указания здесь бесполезны (если человек еще не осознал предыдущее) либо вредны (если он думает, что осознал, на самом деле ничего не понимая). Можно дать лишь общий совет для тех, кто еще занимается (само)образованием.
В математике для программиста важны не столько конкретные результаты (за ними можно обратиться и к справочной литературе), сколько структура понятий и доказательств, способы введения абстракций и применения исключительно абстрактных понятий в частных ситуациях.
Иногда переиспользованию способствует применение развитых языковых средств. В частности, C++ и Java довольно часто позволяют переносить программы из одной операционной обстановки в другую (перенос - одна из форм переиспользования). Но те, кто реально занимался переносом программ, наверняка вспомнят при чтении предыдущего предложения досадные несоответствия, выявлению и предупреждению которых C++ и Java никак не помогают.
Переиспользованию способствует повышение уровня понятий языка, хотя бы до второго-третьего типа (объектная ориентированность языка). Иногда ООП помогает также возможностями наследования свойств и методов объектов (но часто в самых критических ситуациях плохо продуманная концепция наследования столь же сильно и мешает).
Все это - зародыши поддержки стиля программирования, нацеленного на переиспользование. Но в основном сложившаяся практика в значительной степени препятствует переиспользованию, а уровень систем поддержки еще недостаточно высок и неадекватен общей задаче применения данного стиля.
Переиспользование зависит также от общего уровня знаний и умений программиста (тот, кто способен подняться до уровня метода, склонен к переиспользованию, а тот, кто не может подняться выше тактического планирования, обычно избегает его).
Если ограничиться деятельностью программиста, то, прежде всего, нужно указать на два аспекта данного стиля: применение существующих компонентов и разработка переиспользуемых компонентов.
Применение переиспользуемых компонентов характеризуется следующими особенностями стиля:
При разработке переиспользуемых компонентов необходимо учитывать, что подобная разработка всегда требует дополнительных затрат, которые связаны со следующими требованиями:
В характеристиках обоих аспектов программирования от переиспользования нет явного упоминания специфики традиционных моделей вычислений. Поэтому они не зависят от стиля, в котором написаны компоненты, и в значительной степени от особенностей вычислительных систем, на которых они
Рассмотрим ранее представленные стили с точки зрения их приспособленности к сочетанию со стилем переиспользования.
Во-первых, если фрагмент может быть выделен как черный ящик, т. е. нас интересует лишь соотношение между его входными и выходными данными, то он на уровне программы может рассматриваться как самостоятельный узел переработки данных и тем самым получает независимость от состояний программы. В свою очередь, именно это позволяет использовать такой фрагмент, как самостоятельный узел переработки другой программы - переиспользовать его. На этом принципе строятся все библиотечные математические функции, реализацию которых достаточно часто не требуется даже знать при использовании.
Обычными единицами переиспользования при любом стиле программирования являются процедуры. Именно они автономно описываются, и если оказываются независимыми от общего с другими компонентами контекста, то, по сути дела, становятся теми самыми черными ящиками, о которых только что шла речь.
Еще один возможный случай, когда часть, ясно осознанная программистом, состояний внешней программы может быть интерпретирована как гомоморфный образ части (опять же, явно выделенной) состояний компонента (
Как ни странно, немногим лучше приспособлено к сочетанию со стилем переиспользования структурное программирование. Требования к структуре информационного пространства задачи и к согласованию с ним других компонентов программы обеспечивают регламентированные связи между подзадачами, а значит, облегчается (но не исчезает) задача выделения самостоятельных компонентов. В дополнение к полностью самостоятельным переиспользуемым компонентам здесь можно указать на переиспользование, при котором в новом применении обеспечивается необходимая часть контекста (т. е. переиспользуются компонент и эта часть контекста; смотри модули языков Modula-2 и Object Pascal ). Модули можно рассматривать как
Следует отметить, что для рассмотренных случаев задача переиспользования достаточно часто требует модификации того, что предоставляется. Рассмотрим простейший пример, который не выходит за рамки переиспользования черного ящика. Функция вычисления квадратного корня определена только для неотрицательных аргументов. Вопрос: нужна ли в переиспользуемой подпрограмме вычисления этой функции проверка? С одной стороны, она повышает надежность программирования, но с другой - оказывается избыточной, когда точно известно (можно доказать), что аргумент больше нуля. В рамках традиционной техники простых механизмов отключения проверки быть не может, поскольку все они нарушают принцип черного ящика. В
Внимание!
Многовариантность как форма
При использовании сентенциального стиля возможности перестройки переиспользуемого компонента под ситуацию гораздо выше за счет высокоуровневых принципов вычислений. Однако точных практических оценок этого пока что нет. Как правило, повторно используются крупные и содержательно полные фрагменты программ, чаще всего именно те, которые являют собой базовые механизмы, развивающие
Но неимперативность по своей сути лучше приспособлена для переиспользования и, в частности, для шаблонного переиспользования, поскольку соотношения вместо приказов легче автоматически трансформировать или даже просто переинтерпретировать в другой обстановке (отсутствие императивности - еще один фактор, обусловливающий уже не раз упоминавшуюся практически абсолютную переносимость математических результатов). Неудивительно, например, что базы данных-фактов в программах на языке Prolog часто становятся их общими частями.
В событийном программировании заранее предписана декомпозиция программы: выделение в ней уровней генерации событий и их обработки. Уже само это наталкивает на мысль осуществимости общего генератора для однотипных программ. Нельзя забывать и о том, что событийный механизм или управление с помощью приоритетов неизбежно повышает автономность обработчиков: например, они могут не обязательно рассчитывать на определенную последовательность вызовов, и, как следствие, их гибкость повышается.
Сегодня наиболее отлаженными с точки зрения переиспользования являются программы в объектно-ориентированном и в функциональном стиле. Общая причина тому - гибкие средства абстракции соответствующих языков и четкое отделение интерфейсов от реализаций. Это повышает потенциальные и реальные возможности переиспользования. Вместе с тем, скажем, объектно-ориентированный стиль эффективен лишь для достаточно больших систем и тем самым вдохновляет программистов на построение больших систем классов и объектов, которые сильно взаимосвязаны. А это, в свою очередь, заставляет технологизировать разработки. Технология в настоящее время связывается с наработкой типовых моделей фрагментов объектно-ориентированных систем. Создаются
Проектирование с учетом повторного использования результатов в будущем возможно осуществлять на четырех уровнях.
Приведенный перечень упорядочен по степени значимости уровней для переиспользования. Наибольшая эффективность достигается, когда удается при проектировании выйти на уровень решений, но одновременно этот уровень является наиболее сложным и трудоемким для разработки.
В заключение отметим, что условия применения стиля от переиспользования в реальном программировании должны включать в себя оценку как экономических показателей, так и уровня квалификации исполнителей. А это уже функции менеджера проекта, который должен решать, ориентироваться ли на переиспользование (в обоих аспектах) или нет, и если да, то решить многие финансовые и организационные проблемы, выходящие за рамки собственно программирования.
Предупреждение!
Здесь необходима трезвая оценка уровня своих специалистов и организованности работ, поскольку на действительно выгодное для переиспользования решение способны, как правило, лишь высококвалифицированные специалисты в хорошей инфраструктуре.
Программирование от
Не всякое переиспользование уместно считать программированием от
Можно указать следующие характерные случаи применения программирования от
Использование технологического и технического
Стиль программирования от
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.