|
Поэтапная разработка программы
В результате объектного анализа программы выявилась необходимость разработки следующих классов: - класс LorryAndWarehouse - класс объекта, представляющего функционирование реализуемой модели в окне; - компонент Warehouse, объектами которого являются склады; - компонент Lorry, объектами которого являются грузовики; - класс ContrlRegion, объектом которого является зона контроля.
Первый этап. Разработка компонента Warehouse
Интерфейс компонента Warehouse содержит функции, обеспечивающие выгрузку в склад и загрузку из склада в грузовик груза, и событие, сообщающее объектам компонента Lorry о необходимости изменения ими направления движения из-за переполнения или опустошения склада.
Рис. Диаграмма классов компонента Warehouse
Интерфейс компонента Warehouse включает функции Put() и Get(): void Put (); Выгрузить груз из грузовика в склад.
void Get (); Загрузить груз в грузовик из склада.
В интерфейс входит событие, сигнализирующее грузовикам, движущимся к этому складу с грузом о необходимости смены направления движения. Данные события содержаться в объекте класса WarehouseEventArgs и включают свойства Full и Left, определяющие, возникло ли переполнение или опустошение склада, и в каком складе – левом или правом.
Делегат события определим так:
public delegate void DelEvFromWarehouse (object sender, WarehouseEventArgs args); А событие как:
event DelEvFromWarehouse evFromWarehouse;
Для простоты реализации фиксируется максимальная вместимость склада allLoad числом 100. Груз размером 10 загружается в склад или выгружается из склада равными пятью порциями partLoad через 100 мс. (timePeriod), чтобы отобразить продолжительность обслуживания грузовика складом постепенным заполнением прямоугольника, представляющего склад на экране, и обусловить необходимость синхронизации загрузки и разгрузки разных грузовиков. Функции Put() и Get() осуществляют продолжительную загрузку и выгрузку грузовиков, используя потоки. Применение рабочих потоков способствует параллельному выполнению другого множества потоков, используемых объектами компонентов, то есть многопоточному функционированию программы. Компонент Warehouse, написанный на языке C#, наследует интерфейс IWarehouse и класс UserControl, включающий в компонент возможность перерисовки собственной области клиента. Приложение csTestWarehouse позволяет убедиться в работоспособности компонента Warehouse и отладить компонент. Компонент Warehouse размещён в библиотеке csWarehouse с пространством имён csWarehouseDll.
Компонент Warehouse. /////////////// // C# компонент Warehouse using System; using System.Drawing; using System.Threading; using System.Windows.Forms; using System.ComponentModel;
namespace csWarehouseDll { // Класс данных события evFromWarehouse public class WarehouseEventArgs: EventArgs { private bool left; // Признак идентификации склада private bool full; // Признак заполненности склада
public WarehouseEventArgs (bool left, bool full) {this.left= left; this.full= full;}
// Свойство заполнения склада public bool Full {get {return full;}}
// Свойство идентификации склада public bool Left {get {return left;}} }
// Делегат события о переполнении и опустошении склада public delegate void DelEvFromWarehouse (object sender, WarehouseEventArgs args);
// Интерфейс склада public interface IWarehouse { void Put (); // Поместить груз в склад void Get (); // Получить груз из склада event DelEvFromWarehouse evFromWarehouse; // Ссылка на объект // события о переполнении и опустошении склада }
// Компонент склада public class Warehouse: UserControl, IWarehouse { bool left; // Признак идентификации склада int allLoad= 100; // Текущий размер груза в складе int PartLoad= 10; // Размер груза грузовика int partLoad; // Разгружаемая или загружаемая порция груза int numParts= 5; // Количество порций int timePeriod= 100; // Время разгрузки или загрузки // порции груза Thread thr; // Ссылка на объект потока
public event DelEvFromWarehouse evFromWarehouse; // Ссылка // на объект события о переполнении и опустошении склада
// Конструктор public Warehouse (bool left, bool full) { this.left= left; if (!full) allLoad= 0; // Склад пуст }
// Разгрузить груз в склад public void Put () { if (((100 - allLoad) < PartLoad) && (evFromWarehouse!= null)) { // Недостаточно места в складе для разгрузки грузовика WarehouseEventArgs wH= new WarehouseEventArgs (left, true); evFromWarehouse (this, wH); // Сгенерировать событие return; } // Разгрузить грузовик и увеличить порциями груз склада // с помощью потока partLoad= PartLoad; // Определить выгрузку // Создать поток выгрузки склада thr= new Thread (new ThreadStart (Change)); thr.Start (); // Стартовать поток thr.Join (); // Подождать завершения потока }
// Получить груз из склада public void Get () { if (((allLoad) < PartLoad) && (evFromWarehouse!= null)) { // Недостаточно груза в складе для загрузки грузовика WarehouseEventArgs wH= new WarehouseEventArgs (left, false); evFromWarehouse (this, wH); // Сгенерировать событие return; } // Загрузить грузовик и уменьшить порциями груз склада // с помощью потока partLoad= -PartLoad; // Определить выгрузку // Создать поток загрузки склада thr= new Thread (new ThreadStart (Change)); thr.Start (); // Стартовать поток thr.Join (); // Подождать завершения потока }
// Разгрузить или загрузить груз порциями protected void Change () { // Выполнить операцию только с одним грузовиком Monitor.Enter (this); // Начать критическую секцию for (int i= 0; i < numParts; i++) if ((allLoad >= 0 && partLoad < 0) || (allLoad <= 100 && partLoad > 0)) { allLoad += partLoad/numParts; Thread.Sleep (timePeriod); Invalidate (); } Monitor.Exit (this); // Завершить критическую секцию }
// Перерисовать размещение груза в складе protected override void OnPaint (PaintEventArgs e) { base.OnPaint (e); e.Graphics.FillRectangle (new SolidBrush (Color.Yellow), 0, 100 - allLoad, ClientSize.Width, ClientSize.Height); e.Graphics.DrawString (allLoad.ToString (), Font, new System.Drawing.SolidBrush (Color.Blue), 5, 10); } } }
Приложение csTestWarehouse. /////////////// // C# using System; using System.Drawing; using System.Threading; using System.Windows.Forms; using System.ComponentModel; using csWarehouseDll;
namespace csTestWarehouse { class TestWarehouse: Form { Warehouse leftWH, rightWH; // Ссылки на объекты // компонента Warehouse bool leftRight; // Признак направления перемещения грузовиков bool life; // Признак жизни потока управления загрузкой // и выгрузкой складов Thread thr; // Ссылка на поток управления загрузкой // и выгрузкой складов
public TestWarehouse () { // Создать объект левого склада leftWH= new Warehouse (true, true); leftWH.Location= new Point (10, 10); leftWH.Size= new Size (30, 100); leftWH.BackColor= Color.White; leftWH.evFromWarehouse+= new DelEvFromWarehouse (WarehouseHandler); this.Controls.Add (leftWH); leftWH.Show ();
// Создать объект правого склада rightWH= new Warehouse (false, false); rightWH.Location= new Point (100, 10); rightWH.Size= new Size (30, 100); rightWH.BackColor= Color.White; rightWH.evFromWarehouse+= new DelEvFromWarehouse (WarehouseHandler); this.Controls.Add (rightWH); rightWH.Show ();
// Создать и запустить поток управления загрузкой // и выгрузкой складов leftRight= true; life= true; thr= new Thread(new ThreadStart (Go)); thr.Start (); }
// Обработать событие evFromWarehouse void WarehouseHandler (object ob, WarehouseEventArgs arg) { // Выдать информацию о направлении перемещения и // о складе, объект которого сгенерировал событие Console.Write("event evFromWarehouse leftRight=" + leftRight); if (arg.Left) Console.Write(" Компонент leftWH "); else Console.Write(" Компонент rightWH ");
if (arg.Full) Console.WriteLine(" полный"); else Console.WriteLine(" пустой"); Console.WriteLine();
// Изменить направление перемещения грузовиков if((arg.Left && arg.Full)|| (!arg.Left &&!arg.Full)) leftRight= true;
if ((arg.Left &&!arg.Full)|| (!arg.Left && arg.Full)) leftRight= false; }
// Обеспечить загрузку груза в склады и // выгрузку груза из складов void Go () { while (life) { if (leftRight) {leftWH.Get (); rightWH.Put ();} else {leftWH.Put (); rightWH.Get ();} } }
// Завершить поток управления загрузкой // и выгрузкой складов void Finish () { life= false; thr.Join (); }
static void Main () { // Создать объект прикладного окна TestWarehouse testWH= new TestWarehouse (); // Запустить приложение с прикладным окном Application.Run (testWH); // Завершить поток управления загрузкой // и выгрузкой складов testWH.Finish (); } } } /* Result: event evFromWarehouse leftRight= True Компонент leftWH пустой event evFromWarehouse leftRight= False Компонент rightWH полный event evFromWarehouse leftRight= False Компонент leftWH полный event evFromWarehouse leftRight= True Компонент leftWH пустой ... */
Рис. Результат работы приложения csTestWarehouse.
![]() ![]() Что делать, если нет взаимности? А теперь спустимся с небес на землю. Приземлились? Продолжаем разговор... ![]() ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между... ![]() ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры... ![]() Что способствует осуществлению желаний? Стопроцентная, непоколебимая уверенность в своем... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|