Разработать программное обеспечение для терминала формирования ассортимента товаров (витрины). Предусмотреть вывод информации по ассортименту, каждый экземпляр товара имеет свой уникальный код. Код представляет собой числовое значение и его строковый вид в формате штрихкода. Витрина представлена в виде последовательности ячеек (полок) для хранения. В каждой ячейке может храниться максимум один экземпляр товара. При старте программы ассортимент заполнен товаром частично. **Терминал позволяет:** - Выставлять/снимать товар на склад; - Выводить информацию по товару, в отсортированном виде; - Менять товары местами, заменять на новый; - Изменять стандартный способ вывода кода товара; - Определять наличие товара, по коду или наименованию. **Требования:** 1. Запрещается использовать обработку исключительных ситуаций и генерировать исключения. 2. Каждый класс должен быть оформлен в отдельном файле. 3. Придерживайтесь принципа DRY (Don’t repeat yourself). 4. Обязательно наличие комментариев и xml-комментариев. ## Техническое задание ### Раздел 1 Создать в решении новую библиотеку классов для товара, подключить в зависимостях библиотеку для работы со штрихкодами из ЛР1. #### Часть 1 Товар описать в виде абстрактного класса, без виртуальных методов: - Предусмотреть возможность задавать идентификатор товара и его наименование; - Помимо идентификатора, товар должен содержать информацию по штрихкоду, который должен обязательно в каждый раз заново инициализироваться при смене идентификатора товара (Поведение связано с заданиями в других лабораторных); - Требуется дать возможность изменять штрихкод и идентификатор товара; - Изменять наименование товара вне класса, на свое усмотрение. - Перегрузить функцию «`ToString()`» для получения информации по типу товара, наименованию, информации от производных классов и штрихкоду; - Тип товара переопределяется в производных классах. - Формат вывода информации: ![Формат вывода информации](../../Pictures/ЛБ02_01.%20Формат%20вывода%20информации.png) Свойство "Тип товара" не должно быть доступно классам, не являющимися производными от абстрактного класса товара - Класс не должен содержать открытых методов и полей («Класс-Модель»), но может позволять взаимодействовать с информацией по наименованию, коду и способу вывода данного кода. #### Часть 2 Создать класс, производный от абстрактного, согласно своему варианту (вариант А из курсовой по ООП): - Добавить как минимум 3 новых свойства, описывающих класс согласно вашему варианту; - Предоставить базовому классу информацию по его типу товара и выводимой информации на консоль (см. формат вывода ч.1). ### Раздел 3 Создать в решении новую библиотеку классов для витрины, подключить в зависимостях библиотеку для работы со штрихкодами из ЛР1 и товарами, раздела 1 этой лабораторной. #### Часть 1 Витрину представить как класс-контейнер с возможностью выставлять фиксированное количество товара: - У каждой витрины есть свой уникальный числовой код (идентификатор); - Класс-контейнер взаимодействует с товарами только через класс раздела 1 части 1. У класса должен быть только один закрытый конструктор: - Для создания экземпляров класса, запрещается использовать: синглтон, фабричные методы, абстрактные фабрики (паттерны проектирования) и рефлексию (`System.Reflection`); - Способ создания объектов класса должен быть описан только в самом классе витрины; - При создании объектов класса должно явно задаваться количество элементов контейнера, для примера: Витрина **v = 10**, `var v = (Витрина)10` #### Часть 2 Реализовать функционал получения нужного товара по его порядковому номеру (индексу) через оператор индексации \[\]: - При этом обращение по индексу должно соответствовать принципу, как если бы товар снимался из «ячейки», и его можно было не возвращать обратно на место; - Получение товара по индексу, должно учитывать, что место в позиции свободное; - Для случая, если мы выходим за пределы массива, никаких усложненных действий не требуется: - Для получения, вернуть просто вернуть `null`; - Для установки, выйти (`return`). Реализовать методы: - Добавления (в первую пустую ячейку и в конкретную позицию), удаления (аналогично), замены и перестановки товара на витрине, связав их с индексатором класса; - Поиска позиции товара по его идентификатору; - Поиска позиции товара по его наименованию; - Сортировки товаров на витрине по идентификатору; - Сортировки товаров на витрине по наименованию; Перегрузить функцию «`ToString()`» для получения информации по всем элементам, хранящимся в контейнере: - Учитывать пустые ячейки. #### Часть 3 Реализовать возможность добавления к текстовой информации штрихкода товара, информации по идентификатору витрины и номеру позиции на витрине: - Идентификатор витрины и позиция товара не влияют на сам идентификатор товара; - Конечная текстовая информация штрихкода товара на витрине должны быть в формате: «ID товара» «ID витрины» «Позиция»; - Для примера: «1000 10 20», где: - 1000 - «ID товара» - 10 - «ID витрины» - 20 - позиция товара на витрине. - Штрихкод товара на витрине должен меняться автоматически, когда: - меняется его позиция на витрине; - меняется идентификатор витрины; - товар перекладывают на другую витрину; - штрихкод сбрасывается до «ID товара», если менять сам идентификатор товара; - Во всех случаях штрихкод должен полностью пересоздаваться. ## Псевдокод ```cs static void TestLab2() { Console.WriteLine("".PadLeft(80, '=')); Витрина showcase = 5; // Способ создания витрины на 5 мест var sample = new КонкретныйТовар(1000, "ВОЙНА И МИРЬ I", "Л.н. Толстой", 1863, 1000000); var lab2Data = new List<Товар> { new КонкретныйТовар(3000, "ВОЙНА И МИРЬ III", "Л.Н. Толстой", 1867, 300000), new КонкретныйТовар(2000, "ВОЙНА И МИРЬ II", "Л.Н. Толстой", 1865, 200000), new КонкретныйТовар(4000, "ВОЙНА И МИРЬ IV", "Л.Н. Толстой", 1869, 400000) }; foreach (var product in lab2Data) { showcase.Push(product); // допускаемый способ закидывания товара на витрину в пустое место } showcase[4] = sample; //прямая отправка товара на нужную позицию витрины sample.Id++; // Можно изменять идентификатор, при этом на витрине товар утратит свой уникальный штрих код Console.WriteLine(sample); showcase.OrderByName(); // Обязательная сортировка, она же может чинить штрихкоды товаров, т.к. фактически происходит изменение позиций товаров на витрине. showcase.Id++; // можно менять ID витрины Console.WriteLine(showcase); // приведение к строке витрины } ```