что такое спецификация в программировании

Спецификации и их роль в разработке программ

Технология разработки программных продуктов

Составитель Румбешт В.В., кандидат технических наук, доц.

Рецензент Михилев В.М., кандидат технических наук, доц.

Т38 Технология разработки программных продуктов: Методические указания. – Белгород: Изд-во БИЭИ, 2005. – 42 с.

В методических указаниях изложены современные методы специфицирования программного обеспечения такие, как Р-технология
(ГОСТ 19.005–85) и метод структурного анализа. Содержатся задания к выполнению лабораторных работ, посвященных изучению указанных методов.

Предназначены для студентов специальности 22.03.

Ó Белгородский инженерно-экономический
институт (БИЭИ), 2005

ОГЛАВЛЕНИЕ

Спецификации и их роль в разработке программ

Спецификация программы – это описание задачи, которую решает программа. Слово «спецификация» буквально означает «описание» или «получение описания», а «специфицировать» значит «описывать».

В отличие от компьютерной программы спецификация обращена, прежде всего, к человеку и представляет собой описание в терминах, характерных для самой задачи, а не для ее реализации. Спецификация – это задание для программиста, написанное постановщиком задачи. Она служит основой дальнейшей детализации и разработки. С другой стороны, требования к программе, отраженные в техническом задании, также обращены к человеку. Однако спецификация более формально, чем требования, описывает решаемую задачу.

К основным свойствам спецификации можно отнести следующее.

1. Спецификация не должна содержать деталей реализации. В отличие от программы она «говорит», что надо сделать, а не как это делать.

2. Спецификация должна обладать формальностью (однозначностью прочтения, точностью), причем диапазон требований здесь очень широк: от полностью формализованного описания до слегка формализованного. Описание на «естественном языке» обычно считается неудовлетворительным, поскольку оно слишком неформально.

3. Спецификация должна быть понятной (ясной, читабельной). В этом заключается еще одно отличие от программы. В общем случае спецификация должна быть более понятным описанием задачи, чем программа, так как краткость не всегда содействует ясности и понятности.

4. Спецификация должна обладать полнотой описания задачи: ничто существенное не должно быть упущено.

Итак, спецификация – это достаточно точное и достаточно полное описание задачи, которое человеку, участвующему в решении, легче написать, понять и прочесть, чем программисту представить решение этой задачи на доступном ему языке программирования.

Дополненные и уточненные требования к программе – это уже спецификация, которая на пути к готовому программному продукту может претерпеть много изменений, оставаясь спецификацией до тех пор, пока не сможет быть выполнена на машине или пока это выполнение не станет достаточно эффективным.

В спецификации программы имеет смысл выделить по крайней мере две существенно разные части. Одна описывает объекты, действующие в задаче: разбиение задачи на подзадачи; входные и выходные данные, связи между ними, если речь идет о задаче преобразования данных или вычислении функции, процессы и действия, если речь идет о задаче управления или взаимодействия с внешней средой, реакции на исключительные ситуации и т.д. Эта часть называется функциональной спецификацией. Она описывает функцию программы, решающей задачу. Другая часть спецификации касается таких аспектов, как скорость работы программы или используемые ею ресурсы, характеристики аппаратуры, на которой она должна работать, специальные требования к надежности и безопасности и т.д. Эту часть называют эксплуатационной спецификацией.

Спецификациям уделяется все большее внимание, их разработка рассматривается как самостоятельная область технологии и методологии программирования, а сами они — как существенная часть программной документации.

В последнее время появилось большое количество технологий и методов построения функциональных спецификаций, а также языков спецификаций. Для этих языков характерно следующее.

1. Разбиение на уровни абстракций.

2. Ограниченное число элементов, приходящихся на уровень абстракции (не более 7).

3. Ограниченный контекст – включается лишь то, что входит в процесс, а все остальное из рассмотрения исключается.

4. В описание включаются как сами данные, так и действия над ними.

В данных методических указаниях рассмотрим две наиболее распространенные технологии специфицирования: Р-технологию и метод структурного анализа, языки которых можно отнести к так называемым графическим языкам. Эти средства представляют информацию в виде графов и диаграмм, а также содержат определенную методологию построения функциональных спецификаций.

2. Основные принципы Р-технологии

Р-технология была создана в Институте Кибернетики АН УССР. Для написания спецификаций в Р-технологии используется язык нагруженных по дугам ориентированных графов. Конкретная спецификация, созданная с помощью Р-технологии, представляет собой иерархию таких графов, называемых Р-схемами.

На самом деле Р-технология охватывает не только этап специфицирования программ, но и этапы проектирования, кодирования, отладки, и документирования в жизненном цикле программного обеспечения. Она предусматривает следующую цепочку работ по созданию программы:

* построение Р-схемы или иерархии Р-схем, реализующей поставленную задачу;

* генерацию исходного текста программы по заданной Р-схеме;

* компиляцию и компоновку загрузочного модуля программы;

* отладку и тестирование, полученной программы;

* генерацию Р-схемы по исходному тексту программы;

Язык Р-схем является удобной оболочкой, в которую может быть погружен любой язык программирования от ассемблера до языка высокого уровня, и в настоящее время является составной частью Единой системы программной документации (ГОСТ 19.005–85).

2.1. Графические структуры Р-схем

Р-схема — это управляющая структура программы в виде множества возможных путей ее выполнения, изображенных направленными дугами. Структура Р-схем изображается с помощью простых графических элементов таких, как вершины, соединительные дуги и вертикальные линии.

Источник

Сталкиваясь с DDD парадигмой вы точно столкнетесь с спецификацией. Спецификация часто используется вместе с паттерном «Репозиторий». Паттерн «спецификация» предоставляет возможность описывать требования к бизнес-объектам, и затем использовать их (и их композиции) для фильтрации не дублируя запросы.

в Википедии этот паттерн описан так:

«Спецификация» в программировании — это шаблон проектирования, посредством которого представление правил бизнес логики может быть преобразовано в виде цепочки объектов, связанных операциями булевой логики.

Изучив несколько статей про спецификацию с других источников:

я решил объединить информацию с нескольких источников и описать полноценно этот паттерн в этой статье.

Начнем с того что рассмотрим UML схему классического шаблона спецификация:

С появлением Generic’ов код можно переписать проще:

Перейдем от абстракций к более-менее реальному примеру.

Допустим, у нас есть портал который хранит в себе список фильмов и отдает их по определенному запросу:

Давайте представим, что пользователям нужно будет получать фильмы по дате, рейтингу, жанру.

Для этого мы создадим IMovieRepository :

Теперь, когда мы захотим объединить все критерии поиска, код может усложниться, пока добавим еще один метод Find, который обработает все возможные критерии и вернет консолидированный результат:

Проблема возникает тогда, когда нам нужно делать проверку не только на этапе запроса к БД. но и в бизнес логике как тут:

Если на уровне БД нам так же нужно фильтровать фильмы, мы добавим такой метод:

Проблема этих двух примеров в том, что они нарушают DRY принцип, поскольку метод проверки того, что является детским фильмом теперь «расплывается» в 2 метода (а по факту даже в 2 слоя приложения DAL и BLL). В таких случаях нас может выручить паттерн «спецификация». Мы можем создать класс-спецификацию который будет проверять можно ли показывать этот фильм детям и выдавать нам результат:

Этот подход позволяет не только убрать дублирование кода в разных доменных областях, но и позволяет комбинировать спецификации. Это в свою очередь позволяет «Аплаить» сколько спецификаций, сколько нам нужно.

Три случая когда стоит использовать шаблон проектирования «спецификация»:

GenericSpecification

Создавая спецификацию. у может нас появится желание создать генерик который будет обслуживать нужную нам спецификацию, например:

Проблема такой реализации заключается в том что, хоть мы и создаем еще один уровень абстракции, но мы не решаем проблему.

Помните (!) Вынос проблемы на другой уровень абстракции не решает эту проблему.

Строго-типизированные спецификации

Как мы можем исправить проблему которая у нас возникла выше?

Решением этой проблемы будет создание строго-типизированной спецификации. Эта спецификация будет в себе иметь все нужные доменные знания без возможности изменять их извне.

Благодаря такому уровню абстракции, нам не нужно теперь следить за тем как мы создаем спецификации и за их экземплярами, так же это решает проблему дублирования. Спецификации легко поддаются таким операциям как And, Or, Not и тд, для этого нам нужно добавить соответствующий код, например для And операции:

Чего просто не возвращать IQueryable в репозитории?

и потом уже использовать в контроллере (или любом другом месте где вы юзаете этот репозиторий) нужный запрос

Этот подход, по сути, имеет тот же недостаток, что и наша первоначальная реализация: он побуждает нас нарушать принцип DRY, дублируя знания предметной области. Этот метод не предлагает нам ничего с точки зрения консолидации в одном месте.

Вторым недостатком здесь является то, что мы открываем контроль над DAL напрямую в контроллер. Что является болезненной и плохой практикой в многоуровневой архитектуре. Стоит помнить что, реализация IQueryable в значительной степени зависит от того, какой «поставщик» LINQ используется за кулисами, поэтому клиентский код должен знать, что потенциально существуют запросы, которые не могут быть скомпилированы в SQL.

Так же этот код нарушает еще один принцип The Liskov Substitution Principle​ (LSP).

Extension method vs specification

Возникает вопрос: а зачем городить спецификацию, если можно просто создать Extension, например:

Конечно такой подход тоже может использоваться для одного или нескольких сгруппированных условий вместо спецификации. Паттерн спецификация позволяет более гибко работать с фильтрами и операциями And, Or, Not и тд.

Спецификация так же отлично работает и в паре с экстеншн методами.

Например, если вы реализуете SoftDelete подход через Extension:

вы можете спокойно юзать Extension, который будет общим для каждого из DBSet’ов где нужна поддержка SoftDelete и использовать его в паре с конкретными спецификациями в конкретных сервисах (репозиториях).

Источник

Шаблон проектирования «Спецификация»

Предпринимая попытки постичь DDD вы наверняка натолкнетесь на этот паттерн, который часто тесно используется вместе с другим, не менее интересным, паттерном «Репозиторий». Этот паттерн предоставляет возможность описывать требования к бизнес-объектам, и затем использовать их (и их композиции) для фильтрации не дублируя запросы.

Пример

Давайте для примера спроектируем домен для простого группового чата: у нас будут три сущности: Группа и Пользователь, между которыми связь многие-ко-многим (один пользователь может находиться в разных группах, в группе может быть несколько пользователей) и Message представляющий собой сообщение, которое пользователь может написать в какой-либо группе:

Теперь представьте, что вы пишите два метода в Application Service:

Реализация 1 (плохая):

Вы можете позволить сервисам самим строить запросы поверх репозитария:

Реализация 2 (неплохая):

Можно просто описать в контракте репозитария все методы, которые нужны для сервисов спрятав в них фильтрацию, реализация будет выглядить так:

Минусы:
Это реализация лишена недостатка первой, но имеет свой — постепенно ваш репозитарий будет разрастаться и распухать и, в конце концов, превратится во что-то слабо поддерживаемое.

Реализация 3 (отличная):

Тут на помощь к нам и приходит паттерн Спецификация, благодаря которому наш код будет выглядеть так:

Реализация паттерна

Мартин Фаулер (и Эрик Эванс) предложил следующий интерфейс спецификации:

Ребята из linqspecs.codeplex.com cделали его более дружественным к репозитарию (его конкретным реализациям на основе EF, nHibernate и т.п.) и даже серилизуемыми:

Благодаря ExpressionTree репозиторий сможет распарсить выражение и транслировать его в SQL или во что-либо ещё. Базовая реализация c основными логическими элементами выглядит так:

Теперь нам осталось лишь для каждой сущности (агрегата) написать статический класс, содержащий спецификации. Для нашего примера он будет выглядеть следующим образом:

Заключение

Вот таким образом мы избавились от дублирования условий даже в нашем небольшом примере, но по настоящему оценить это можно на больших проектах со сложной логикой. В этом и беда DDD, что его объясняют всегда на небольших примерах и трудно отделаться от мысли, что всё это оверинженеринг.

Источник

Шаблон проектирования «Спецификация» в C#

«Спецификация» в программировании — это шаблон проектирования, посредством которого представление правил бизнес логики может быть преобразовано в виде цепочки объектов, связанных операциями булевой логики.

Если коротко, основное преимущество от использования «спецификаций» в том, чтобы иметь одно понятное место, в котором сосредоточены все правила фильтрации объектов предметной модели, вместо тысячи размазанных ровным слоем по приложению лямбда-выражений.

Классическая реализация шаблона проектирования выглядит так:

Что с ним не так применительно к C#?

В конечном итоге возникает вопрос: стоит ли в C# пользоваться шаблоном десятилетней давности из мира Java и как его реализовать?

Мы решили, что стоит вот таким образом:

В конечном итоге, эти рассуждения навели на мысль, что самый простой способ – модифицировать целевой IQueryable и передавать далее через fluent interface. Дополнительные методы Where позволяют коду выглядеть, словно это обычная цепочка LINQ-преобразований.

Руководствуясь этой логикой, можно выделить абстракцию для сортировки

Есть такая библотека: LinqSpecs. Не нравится мне в ней то, что нужно создавать отдельные типы спецификаций на каждый чих. По мне достаточно Expression >

Воспользуемся Predicate Builder от Pete Montgomery.

Детали реализации метода Compose объяснены по ссылке выше. Теперь добавим синтаксический сахар, чтобы можно было использовать && и || и ограничение IHasId на generic, потому что я не заинтересован в создании спецификаций для Value Object. Данное ограничение не является необходимым, просто мне так кажется лучше.

Я привык записывать «выражения-спецификации» статическими полями в классе сущности, к которой они относятся:

С учетом кода выше можно переписать вот так:

Источник

Шаблон проектирования Спецификация

Паттерн “спецификация” предоставляет возможность описывать требования к бизнес-объектам, и затем использовать их (и их композиции) для фильтрации не дублируя запросы.

Что такое спецификация?

В Википедии этот паттерн описан так:

«Спецификация» в программировании — это шаблон проектирования, посредством которого представление правил бизнес логики может быть преобразовано в виде цепочки объектов, связанных операциями булевой логики.

Изучив несколько статей про спецификацию с других источников, я решил объединить информацию с нескольких источников и описать полноценно этот паттерн в этой статье.

UML схема классического шаблона спецификация:

Немного теории

Для абстрактного понимания шаблона спецификации можно глянуть здесь. А мы перейдем к более-менее реальному примеру.

Допустим, у нас есть интернет магазин. У нас есть товары и товарные предложения. Каждый товар имеет название, цену и кол-во на складе.

Само приложение может отдавать нам список товаров на странице категории, на главной странице, в различных блоках на сайте, например, последние просмотренные товары, рекомендуемые товары, с этим товаром покупают и т.д.

При обычном подходе многие пишут код так: в каждом случае делается отдельный метод/экшен/вью композер/компонент, который отвечает за свою логику. Делает шаблон для вывода этого товара. И в этом шаблоне описывает логику кнопки “Заказать”. А именно, проверяет, что товара достаточно на складе.

А что если завтра бизнес нам скажет, что хочет добавить выключатель товара, который когда выключаешь, то товар становился не доступен для заказа? Тогда разработчик пойдет во все шаблоны добавлять новый функционал, новое условие. По пути где-то ошибется с условием, где-то забудет поправить или пропустит по иной причине. Так и случается лапшекод.

И мы пока рассмотрели с вами лишь вопрос с кнопкой в шаблонах. Но точно такие же условия у нас будут в сервисе корзины, чтобы проверить, можно ли данный товар добавить в корзину. Такое же условие будет в сервисе резервирования товара, чтобы понимать, можем ли мы этот товар зарезервировать.

Так как решить этот вопрос? Все очень просто. Необходимо все эти условия вынести в отдельный класс Specification.

Реализация

Имеем класс товара

Напишем спецификацию на проверку доступного кол-ва товаров

Теперь напишем общую спецификацию на то, что товар доступен для заказа

Теперь везде, где потребуется проверка на доступность к заказу, мы используем следующий подход

Т.к. мы вынесли в отдельный класс нашу проверку, то когда к нам придет бизнес и попросит добавить еще одну проверку для доступности покупки товара, нам достаточно будет создать еще одну спецификацию, например, VisibleSpecification

И добавить его в нашу единую спецификацию

Т.к. мы выносим все проверки в отдельные спецификации мы можем использовать их как по отдельности, так и составлять из них более сложные спецификации как на примере кода выше. Так же эти спецификации хорошо тестируются.

Не забывайте использовать в своих проектах паттерны проектирования, SOLID, KISS и DRY подходы. Да прибудет с вами чистый код.

Источник

Понравилась статья? Поделиться с друзьями:

Не пропустите наши новые статьи:

  • Что такое специфика программы
  • что такое специальные программы обучения
  • что такое специальное программное обеспечение
  • что такое специализированное программное обеспечение
  • что такое спеки в программировании

  • Операционные системы и программное обеспечение
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest
    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии