| 
 | 
			
			Поэтапная разработка программы
 В результате объектного анализа программы выявилась необходимость разработки следующих классов: - класс 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. 
 
 ![]()   ЧТО ПРОИСХОДИТ, КОГДА МЫ ССОРИМСЯ Не понимая различий, существующих между мужчинами и женщинами, очень легко довести дело до ссоры...   Что будет с Землей, если ось ее сместится на 6666 км? Что будет с Землей? - задался я вопросом...   ЧТО ПРОИСХОДИТ ВО ВЗРОСЛОЙ ЖИЗНИ? Если вы все еще «неправильно» связаны с матерью, вы избегаете отделения и независимого взрослого существования...   ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте: 
  |