Сдам Сам

ПОЛЕЗНОЕ


КАТЕГОРИИ







Поэтапная разработка программы





 

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

- класс 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.

 

 









Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:


©2015- 2018 zdamsam.ru Размещенные материалы защищены законодательством РФ.