Учебники. Программирование для начинающих.
Programm.ws — это сайт, на котором вы можете почитать литературу по языкам программирования , а так-же посмотреть примеры работающих программ на С++, ассемблере, паскале и много другого..
Программирование — в обычном понимании, это процесс создания компьютерных программ.
В узком смысле (так называемое кодирование) под программированием понимается написание инструкций — программ — на конкретном языке программирования (часто по уже имеющемуся алгоритму — плану, методу решения поставленной задачи). Соответственно, люди, которые этим занимаются, называются программистами (на профессиональном жаргоне — кодерами), а те, кто разрабатывает алгоритмы — алгоритмистами, специалистами предметной области, математиками.
В более широком смысле под программированием понимают весь спектр деятельности, связанный с созданием и поддержанием в рабочем состоянии программ — программного обеспечения ЭВМ. Более точен современный термин — «программная инженерия» (также иначе «инженерия ПО»). Сюда входят анализ и постановка задачи, проектирование программы, построение алгоритмов, разработка структур данных, написание текстов программ, отладка и тестирование программы (испытания программы), документирование, настройка (конфигурирование), доработка и сопровождение.
Delphi для начинающих
Глава 1. Основы программирования
Спецификация
Спецификация, определение требований к программе — один из важнейших этапов, на котором подробно описывается исходная информация, формулируются требования к результату, поведение программы в особых случаях (например, при вводе неверных данных), разрабатываются диалоговые окна, обеспечивающие взаимодействие пользователя и программы.
Понятие «спецификация программы»
Средства спецификации — это любые средства получения и построения таких описаний. Язык спецификаций — это рационально организованный и синтаксически оформленный набор таких средств.
- 3. [163] Спецификация программы — это точная и полная формулировка задачи, содержащая информацию, необходимую для построения алгоритма (программы) решения этой задачи.
- 4. Команда-комментарий — это спецификация программы, выраженная с помощью помещённого в программу утверждения (или приказа) на псевдокоде.
Мы часто вынуждены обращаться к формальным спецификациям, так как естественный язык (используемый в псевдокоде) обладает таким свойством, как полисемия.
Определение [141].
Полисемия — это наличие различных (но в какой-то мере связанных) смыслов и(или) значений у одного и того же слова (словосочетания, фразы), различных интерпретаций у одного и того же знака или знакосочетания.
Пусть PL — некоторый язык программирования (в частности, им может являться один из модельных языков Н, D, М), АР1— его алфавит, G — алфавит языка первого порядка.
Определение (синтаксическое).
1. Формальной спецификацией программы S будем называть слово
в алфавите G и АР1 и [1] , где Q, и R — формулы языка первого порядка, S — программа на языке PL.
Предусловием программы S называется формула Q.
Пустым предусловием программы S называется предусловие Q= S H
Постусловием программы S называется формула R.
2. Языком спецификаций назовём язык для записи предусловий и постусловий.
1. [88, с. 107] Для задачи о суммировании элементов массива В [0: п -1] и помещении результата в переменную S предусловие и постусловие имеют следующий вид:
2. Для вычисления целой части квадратного корня из натурального числа п и помещения результата в целочисленную переменную S предусловие и постусловие имеют следующий вид:
3. Для задачи сортировки массива В [0: п — 1] предусловие и постусловие имеют следующий вид:
Определение (no [88, c. 106]) (семантическое).
Интерпретация формальной спецификации S такова: если выполнение программы S началось в состоянии, удовлетворяющем Q, то имеется гарантия, что оно завершится через конечное время в состоянии, удовлетворяющем R.
- 1. Утверждением будем называть содержательную или формальную спецификацию, включённую в текст программы.
- 2. Аннотированной программой будем называть программу, содержащую утверждения между каждой парой соседних команд.
Итак, аннотированная программа является «формулой» в языке вида:
Язык программирования + Язык спецификаций.
Использование аннотированных программ открывает широкие возможности для формальных преобразований программ и формальных доказательств их свойств, что является основой для верификации и оптимизации программ.
Спецификация программной системы
Спецификация программной системы — описание системы, которое полностью определяет ее цель и функциональные возможности. Различают:
— словесные спецификации на естественном языке;
— модельные спецификации;
— формальные спецификации.
См. также: Спецификации программных систем Спецификации Жизненный цикл программного обеспечения
Финансовый словарь Финам .
- Спецификация опциона
- Спецификация фьючерса
Смотреть что такое «Спецификация программной системы» в других словарях:
- Функциональная спецификация — Разработка программного обеспечения Процесс разработки ПО Шаги процесса Анализ • Проектирование • Программирование • Докумен … Википедия
- Формальная спецификация — В информатике формальная спецификация это математическое описание программной или аппаратной системы, которая может быть реализована в соответствии с этим описанием. Специфицируется, что должна делать система, но не то, как она должна это… … Википедия
- UML — (англ. Unified Modeling Language унифицированный язык моделирования) язык графического описания для объектного моделирования в области разработки программного обеспечения. UML является языком широкого профиля, это открытый… … Википедия
- Unified Modeling Language — UML (сокр. от англ. Unified Modeling Language унифицированный язык моделирования) язык графического описания для объектного моделирования в области разработки программного обеспечения. UML является языком широкого профиля, это открытый стандарт … Википедия
- Гради Буч — UML (сокр. от англ. Unified Modeling Language унифицированный язык моделирования) язык графического описания для объектного моделирования в области разработки программного обеспечения. UML является языком широкого профиля, это открытый стандарт … Википедия
- ГОСТ Р МЭК 61508-4-2007: Функциональная безопасность систем электрических, электронных, программируемых электронных, связанных с безопасностью. Часть 4. Термины и определения — Терминология ГОСТ Р МЭК 61508 4 2007: Функциональная безопасность систем электрических, электронных, программируемых электронных, связанных с безопасностью. Часть 4. Термины и определения оригинал документа: 3.7.4 анализ влияния (impact analysis) … Словарь-справочник терминов нормативно-технической документации
- Требования к программному обеспечению — Для улучшения этой статьи желательно?: Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное. Проставив сноски, внести более точные указания на источники. Пере … Википедия
- Разработка программного обеспечения — Когда Грейс Хоппер работала с компьютером Гарвард Марк II в Гарвардском университете, её коллеги обнаружили эту моль, застрявшую в реле и таким образом помешавшую работе устройства, после чего она отметила, что они «отлаживали»(debug) систему.… … Википедия
- Прецедент (UML) — У этого термина существуют и другие значения, см. Прецедент (значения). Основная статья: Сценарий использования Прецедент (англ. Use Case), также: вариант использования, сценарий использования спецификация последовательностей действий… … Википедия
- Use case — Прецедент (англ. Use Case, а также: вариант использования, сценарий использования) спецификация последовательностей действий (варианты последовательностей и ошибочные последовательности), которые может осуществлять система, подсистема или класс,… … Википедия
- Обратная связь: Техподдержка, Реклама на сайте
- Путешествия
Экспорт словарей на сайты, сделанные на PHP,
WordPress, MODx.
- Пометить текст и поделитьсяИскать в этом же словареИскать синонимы
- Искать во всех словарях
- Искать в переводах
- Искать в ИнтернетеИскать в этой же категории
Поделиться ссылкой на выделенное
Прямая ссылка:
… Нажмите правой клавишей мыши и выберите «Копировать ссылку»
Паттерн проектирования «Спецификация» в .NET
Сталкиваясь с DDD парадигмой вы точно столкнетесь с спецификацией. Спецификация часто используется вместе с паттерном «Репозиторий». Паттерн «спецификация» предоставляет возможность описывать требования к бизнес-объектам, и затем использовать их (и их композиции) для фильтрации не дублируя запросы. в Википедии этот паттерн описан так:
«Спецификация» в программировании — это шаблон проектирования, посредством которого представление правил бизнес логики может быть преобразовано в виде цепочки объектов, связанных операциями булевой логики.
- Шаблон проектирования «Спецификация»;
- Шаблон проектирования «Спецификация» в C#;
- Прогноз на Specification pattern в Domain layer — ожидаются проблемы;
- Specification pattern: C# implementation;
я решил объединить информацию с нескольких источников и описать полноценно этот паттерн в этой статье.
Начнем с того что рассмотрим UML схему классического шаблона спецификация:
Классическая реализация спецификации в .NET будет выглядеть следующим образом:
public interface ISpecification < bool IsSatisfiedBy(object candidate); ISpecification And(ISpecification other); ISpecification AndNot(ISpecification other); ISpecification Or(ISpecification other); ISpecification OrNot(ISpecification other); ISpecification Not(); >public abstract class CompositeSpecification : ISpecification < public abstract bool IsSatisfiedBy(object candidate); public ISpecification And(ISpecification other) < return new AndSpecification(this, other); >public ISpecification AndNot(ISpecification other) < return new AndNotSpecification(this, other); >public ISpecification Or(ISpecification other) < return new OrSpecification(this, other); >public ISpecification OrNot(ISpecification other) < return new OrNotSpecification(this, other); >public ISpecification Not() < return new NotSpecification(this); >> public class AndSpecification : CompositeSpecification < private readonly ISpecification _leftCondition; private readonly ISpecification _rightCondition; public AndSpecification(ISpecification left, ISpecification right) < _leftCondition = left; _rightCondition = right; >public override bool IsSatisfiedBy(object candidate) < return _leftCondition.IsSatisfiedBy(candidate) && _rightCondition.IsSatisfiedBy(candidate); >> public class AndNotSpecification : CompositeSpecification < private readonly ISpecification _leftCondition; private readonly ISpecification _rightCondition; public AndNotSpecification(ISpecification left, ISpecification right) < _leftCondition = left; _rightCondition = right; >public override bool IsSatisfiedBy(object candidate) < return _leftCondition.IsSatisfiedBy(candidate) && _rightCondition.IsSatisfiedBy(candidate) != true; >> public class OrSpecification : CompositeSpecification < private readonly ISpecification _leftCondition; private readonly ISpecification _rightCondition; public OrSpecification(ISpecification left, ISpecification right) < _leftCondition = left; _rightCondition = right; >public override bool IsSatisfiedBy(object candidate) < return _leftCondition.IsSatisfiedBy(candidate) || _rightCondition.IsSatisfiedBy(candidate); >> public class OrNotSpecification : CompositeSpecification < private readonly ISpecification _leftCondition; private readonly ISpecification _rightCondition; public OrNotSpecification(ISpecification left, ISpecification right) < _leftCondition = left; _rightCondition = right; >public override bool IsSatisfiedBy(object candidate) < return _leftCondition.IsSatisfiedBy(candidate) || _rightCondition.IsSatisfiedBy(candidate) != true; >> public class NotSpecification : CompositeSpecification < private readonly ISpecification _wrapped; public NotSpecification(ISpecification x) < _wrapped = x; >public override bool IsSatisfiedBy(object candidate) < return !_wrapped.IsSatisfiedBy(candidate); >>
С появлением Generic’ов код можно переписать проще:
public interface ISpecification < bool IsSatisfiedBy(T candidate); ISpecificationAnd(ISpecification other); ISpecification AndNot(ISpecification other); ISpecification Or(ISpecification other); ISpecification OrNot(ISpecification other); ISpecification Not(); > public abstract class LinqSpecification : CompositeSpecification < public abstract Expression> AsExpression(); public override bool IsSatisfiedBy(T candidate) => AsExpression().Compile()(candidate); > public abstract class CompositeSpecification : ISpecification < public abstract bool IsSatisfiedBy(T candidate); public ISpecificationAnd(ISpecification other) => new AndSpecification(this, other); public ISpecification AndNot(ISpecification other) => new AndNotSpecification(this, other); public ISpecification Or(ISpecification other) => new OrSpecification(this, other); public ISpecification OrNot(ISpecification other) => new OrNotSpecification(this, other); public ISpecification Not() => new NotSpecification(this); > public class AndSpecification : CompositeSpecification < readonly ISpecification_left; readonly ISpecification _right; public AndSpecification(ISpecification left, ISpecification right) < _left = left; _right = right; >public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) && _right.IsSatisfiedBy(candidate); > public class AndNotSpecification : CompositeSpecification < readonly ISpecification_left; readonly ISpecification _right; public AndNotSpecification(ISpecification left, ISpecification right) < _left = left; _right = right; >public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) && !_right.IsSatisfiedBy(candidate); > public class OrSpecification : CompositeSpecification < readonly ISpecification_left; readonly ISpecification _right; public OrSpecification(ISpecification left, ISpecification right) < _left = left; _right = right; >public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) || _right.IsSatisfiedBy(candidate); > public class OrNotSpecification : CompositeSpecification < readonly ISpecification_left; readonly ISpecification _right; public OrNotSpecification(ISpecification left, ISpecification right) < _left = left; _right = right; >public override bool IsSatisfiedBy(T candidate) => _left.IsSatisfiedBy(candidate) || !_right.IsSatisfiedBy(candidate); > public class NotSpecification : CompositeSpecification < readonly ISpecification_other; public NotSpecification(ISpecification other) => _other = other; public override bool IsSatisfiedBy(T candidate) => !_other.IsSatisfiedBy(candidate); >
Перейдем от абстракций к более-менее реальному примеру.
Допустим, у нас есть портал который хранит в себе список фильмов и отдает их по определенному запросу:
public class Movie : Entity < public string Name < get; >public DateTime ReleaseDate < get; >public MpaaRating MpaaRating < get; >public string Genre < get; >public double Rating < get; >> public enum MpaaRating
Давайте представим, что пользователям нужно будет получать фильмы по дате, рейтингу, жанру.
Для этого мы создадим IMovieRepository :
public interface IMovieRepository < IReadOnlyListGetByReleaseDate(DateTime maxReleaseDate); IReadOnlyList GetByRating(double minRating); IReadOnlyList GetByGenre(string genre); >
Теперь, когда мы захотим объединить все критерии поиска, код может усложниться, пока добавим еще один метод Find, который обработает все возможные критерии и вернет консолидированный результат:
public class MovieRepository < public IReadOnlyListFind( DateTime? maxReleaseDate = null, double minRating = 0, string genre = null) < /* . */ >>
Проблема возникает тогда, когда нам нужно делать проверку не только на этапе запроса к БД. но и в бизнес логике как тут:
public ResultBuyChildTicket(int movieId)
Если на уровне БД нам так же нужно фильтровать фильмы, мы добавим такой метод:
public class MovieRepository < public IReadOnlyListFindMoviesForChildren() < return db .Where(x =>x.MpaaRating == MpaaRating.G) .ToList(); > >
Проблема этих двух примеров в том, что они нарушают DRY принцип, поскольку метод проверки того, что является детским фильмом теперь «расплывается» в 2 метода (а по факту даже в 2 слоя приложения DAL и BLL). В таких случаях нас может выручить паттерн «спецификация». Мы можем создать класс-спецификацию который будет проверять можно ли показывать этот фильм детям и выдавать нам результат:
public ResultBuyChildTicket(int movieId) < Movie movie = _repository.GetById(movieId); var spec = new MovieForKidsSpecification(); if (!spec.IsSatisfiedBy(movie)) return Error("The movie is not eligible for children"); return Ok(); >public class MovieRepository < public IReadOnlyListFind(Specification specification) < /* . */ >>
Этот подход позволяет не только убрать дублирование кода в разных доменных областях, но и позволяет комбинировать спецификации. Это в свою очередь позволяет «Аплаить» сколько спецификаций, сколько нам нужно.
Три случая когда стоит использовать шаблон проектирования «спецификация»:
- Поиск данных в базе данных. Это поиск записей который соответствуют спецификации, которую мы имеем реализовали.
- Проверка объектов в памяти. Другими словами, проверка того, что объект, который мы извлекли из БД соответствует спецификации.
- Создание нового экземпляра, который соответствует критериям. Это полезно в тех случаях, когда вы не заботитесь о реальном содержании экземпляров, но все же должны иметь определенные атрибуты.
GenericSpecification
Создавая спецификацию. у может нас появится желание создать генерик который будет обслуживать нужную нам спецификацию, например:
public class GenericSpecification < public Expression> Expression < get; >public GenericSpecification(Expression> expression) < Expression = expression; >public bool IsSatisfiedBy(T entity) < return Expression.Compile().Invoke(entity); >> // Controller public void SomeMethod() < var specification = new GenericSpecification( m => m.MpaaRating == MpaaRating.G); bool isOk = specification.IsSatisfiedBy(movie); // Exercising a single movie var movies = _repository.Find(specification); // Getting a list of movies > // Repository public IReadOnlyList Find(GenericSpecification specification)
Проблема такой реализации заключается в том что, хоть мы и создаем еще один уровень абстракции, но мы не решаем проблему.
Помните (!) Вынос проблемы на другой уровень абстракции не решает эту проблему.
Generic спецификация не помогает решить DRY диллему, а значит не сильно нам подходит, да и в целом GenericSpecification — это плохая практика тк сами по себе они бесполезны.
Строго-типизированные спецификации
Как мы можем исправить проблему которая у нас возникла выше?
Решением этой проблемы будет создание строго-типизированной спецификации. Эта спецификация будет в себе иметь все нужные доменные знания без возможности изменять их извне.
Перепишем наш код:
public abstract class Specification < public abstract Expression> ToExpression(); public bool IsSatisfiedBy(T entity) < Funcpredicate = ToExpression().Compile(); return predicate(entity); > > public class MpaaRatingAtMostSpecification : Specification < private readonly MpaaRating_rating; public MpaaRatingAtMostSpecification(MpaaRating rating) < _rating = rating; >public override Expression> ToExpression() < return movie =>movie.MpaaRating > // Controller public void SomeMethod() < var gRating = new MpaaRatingAtMostSpecification(MpaaRating.G); bool isOk = gRating.IsSatisfiedBy(movie); // Exercising a single movie IReadOnlyListmovies = repository.Find(gRating); // Getting a list of movies > // Repository public IReadOnlyList Find(Specification specification) < using (ISession session = SessionFactory.OpenSession()) < return session.Query() .Where(specification.ToExpression()) .ToList(); > >
Благодаря такому уровню абстракции, нам не нужно теперь следить за тем как мы создаем спецификации и за их экземплярами, так же это решает проблему дублирования. Спецификации легко поддаются таким операциям как And, Or, Not и тд, для этого нам нужно добавить соответствующий код, например для And операции:
public abstract class Specification < public SpecificationAnd(Specification specification) < return new AndSpecification(this, specification); > // And also Or and Not methods > public class AndSpecification : Specification < private readonly Specification_left; private readonly Specification _right; public AndSpecification(Specification left, Specification right) < _right = right; _left = left; >public override Expression> ToExpression() < Expression> leftExpression = _left.ToExpression(); Expression> rightExpression = _right.ToExpression(); BinaryExpression andExpression = Expression.AndAlso( leftExpression.Body, rightExpression.Body); return Expression.Lambda>( andExpression, leftExpression.Parameters.Single()); > > var gRating = new MpaaRatingAtMostSpecification(MpaaRating.G); var goodMovie = new GoodMovieSpecification(); var repository = new MovieRepository(); IReadOnlyList movies = repository.Find(gRating.And(goodMovie));
Чего просто не возвращать IQueryable в репозитории?
Разве не проще позволить клиентам запрашивать те данные которые они хотят реализовав метод Find который возвращает IQueryable ?
// Repository public IQueryable Find() < return session.Query(); >
и потом уже использовать в контроллере (или любом другом месте где вы юзаете этот репозиторий) нужный запрос
public void SomeMethod() < Listmovies = _repository.Find() .Where(movie => movie.MpaaRating == MpaaRating.G) .ToList(); >
Этот подход, по сути, имеет тот же недостаток, что и наша первоначальная реализация: он побуждает нас нарушать принцип DRY, дублируя знания предметной области. Этот метод не предлагает нам ничего с точки зрения консолидации в одном месте.
Вторым недостатком здесь является то, что мы открываем контроль над DAL напрямую в контроллер. Что является болезненной и плохой практикой в многоуровневой архитектуре. Стоит помнить что, реализация IQueryable в значительной степени зависит от того, какой «поставщик» LINQ используется за кулисами, поэтому клиентский код должен знать, что потенциально существуют запросы, которые не могут быть скомпилированы в SQL.
Так же этот код нарушает еще один принцип The Liskov Substitution Principle (LSP).
Extension method vs specification
Возникает вопрос: а зачем городить спецификацию, если можно просто создать Extension, например:
public class MoviesExtensions < public static IQueryableIsForChild(this IQueryable users, MpaaRating rating) < return users.Where(x =>x.MpaaRating == rating); > >
Конечно такой подход тоже может использоваться для одного или нескольких сгруппированных условий вместо спецификации. Паттерн спецификация позволяет более гибко работать с фильтрами и операциями And, Or, Not и тд.
Спецификация так же отлично работает и в паре с экстеншн методами.
Например, если вы реализуете SoftDelete подход через Extension:
public static IQueryable Undeleted(this IQueryable queryable) where T : Entity < return queryable.Where(x =>!x.IsDeleted); >
вы можете спокойно юзать Extension, который будет общим для каждого из DBSet’ов где нужна поддержка SoftDelete и использовать его в паре с конкретными спецификациями в конкретных сервисах (репозиториях).
Итоги:
- Не используйте GenericSpecification в паре с Expression> в качестве реализации шаблона спецификаций, они не позволяют фактически собрать знания о предметной области в одно место.
- Не возвращайте IQueryable из репозиториев, это вызывает проблемы с нарушением DRY и LSP.
- Тот или иной паттерн не панацея от всех проблем, используйте паттерны с умом и применяйте их там где они действительно нужны, помните и про такие принципы как YAGNI и KISS.