Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методич.указания к заданиям по ТП.doc
Скачиваний:
4
Добавлен:
06.05.2019
Размер:
897.02 Кб
Скачать

6. Описание проблем, возникших при разработке программной системы.

Поэтапная разработка программы позволила быстро разработать её и отладить. Но тем ни менее, возникли некоторые трудности при реализации функций Get() и Put() компонента склада Warehouse. Также при удалении объектов грузовиков пришлось ввести в обработчик корректировку совокупности номеров интерфейсного элемента списка.

7. Список используемой литературы

1. . Медведев В.И. .NET компоненты, контейнеры и удалённые объекты (Серия «Современная прикладная математика и информатика»). – Казань: РИЦ «Школа», 2007. – 320 c.: ил.

2. Медведев В.И. .NET компонентно-ориентированное программирование (Серия “Современная прикладная математика и информатика”). (издается) – Казань: РИЦ «Школа», 2012. – 277 c.: ил.

3.Медведев В.И. Особенности объектно-ориентированного программирования на C++/CLI, C# и Java. 3-е изд., испр. и доп. – Казань: РИЦ «Школа», 2011. – 430 c.: ил

4.Медведев В.И. Особенности объектно-ориентированного программирования на C++/CLI, C# и Java. 2-е изд., испр. и доп. – Казань: РИЦ «Школа», 2010. – 444 c.: ил

5. Juval Lowy. Programming .NET Components. 2nd Edition. – O’Reilly Media,

2005. – 626 pp.

6 Ingo Rammer, Mario Szpuszta. Advanced .NET Remoting. 2nd Edition. – Apress, 2005. – 579 pp.

7. Рамбо Дж., Якобсон А., Буч Г. UML: специальный справочник. – СПб.: Питер, 2002. – 656 c.

10. Разработка многокомпонентной программы с удалённым объектом

Модифицируем разработанную многокомпонентную программу LorryEndWarehouse, разбив её на сервер и клиент и связав клиент с сервером удалённым объектом. Эту связь можно осуществить по-разному, предложив разные удалённые объекты. Удалённые объекты могут быть функционально простыми и осуществлять только минимальные требуемые связи клиента с сервером, а основное функционирование программы осуществится остальной часть сервера и клиента. Но удаленный объект может быть изощрённым, возлагая на себя огромную часть функционирования сервера, на котором он размещён. Какой вариант предпочтителен, выбирает разработчик программы. Возможно, первый. Главное – любой удалённый объект обязан наследовать класс MarshalByRefObject, непосредственно или через другой наследуемый класс.

Модифицируя программу LorryEndWarehouse, предложим несколько вариантов её реализации с отличающимися удалёнными объектами.

В первом варианте удалённый объект сложный и представляет собой прикладное окно сервера со складами, зоной контроля, перемещающимися грузовиками и объектом контейнера. Класс RemObj этого удаленного объекта наследует класс Form, который в свою очередь наследует класс MarshalByRefObject. Во втором же варианте, рассмотренном позднее, модифицированный класс RemObj удалённого объекта простой и наследует непосредственно класс MarshalByRefObject.

10.1. Удалённый компонент RemObj

Рис. Диаграмма классов удалённого компонента RemObj

Класс RemObj удалённого объекта размещён в пространстве имён csLorryAndWarehouseRemotingDll библиотеки csLorryAndWarehouseRemoting.

Удалённый компонент RemObj.

///////////////

// C# File csLorryAndWarehouseRemoting

using System;

using System.ComponentModel;

using System.Collections;

using System.Drawing;

using System.Threading;

using System.Windows.Forms;

using csLorryDll;

using csWarehouseDll;

using csContrlRegionDll;

namespace csLorryAndWarehouseRemotingDll

{

// Интерфейс контейнера грузовиков

interface ILorryContainer

{

void AddLorry ( );

void RemoveLorry (int carrNumber);

void RemoveAllLorries ( );

ArrayList GetNumLorries ( );

void RunLorries ( );

void StopLorries ( );

void ShowComponents ( );

}

// Контейнер грузовиков

class LorryContainer: Container, ILorryContainer

{

Warehouse leftWH; // Ссылки на объект левого склада

Warehouse rightWH; // Ссылки на объект правого склада

ContrlRegion region; // Ссылка на объект зоны контроля

bool leftRight; // Признак направления перемещения

// грузовиков

int numCarr= 0; // Номер грузовика

int Y; // Координата Y пути грузовика

Random rand; // Ссылка на случайное число

// Конструктор

public LorryContainer (Warehouse leftWH, Warehouse rightWH,

ContrlRegion region)

{

this.leftWH= leftWH; this.rightWH= rightWH;

this.region= region;

Y= 20; rand= new Random ( );

leftRight= true;

leftWH.evFromWarehouse += new DelEvFromWarehouse

(this.EvFromWarehouseHandler);

rightWH.evFromWarehouse += new DelEvFromWarehouse

(this.EvFromWarehouseHandler);

}

// Добавить грузовик

public void AddLorry ( )

{

numCarr++;

Y += 20;

int dX = rand.Next (5, 10);

if (leftRight) dX= dX;

else dX= -dX;

Lorry lorry= new Lorry (numCarr, Y, dX, leftWH, rightWH,

region);

base.Add (lorry);

lorry.Start ( );

}

// Удалить грузовик

public void RemoveLorry (int lorryNumber)

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

if (comp.Number == lorryNumber)

{

comp.Finish ( );

base.Remove (comp);

return;

}

}

}

// Получить список номеров грузовиков

public ArrayList GetNumLorries ( )

{

ArrayList arList= new ArrayList ( );

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

arList.Add (comp.Number);

}

return arList;

}

// Возобновить движение грузовиков

public void RunLorries ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.Run ( );

}

}

// Приостановить движение грузовиков

public void StopLorries ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.Stop ( );

}

}

// Удалить все грузовики

public void RemoveAllLorries ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.Finish ( );

base.Remove (comp);

}

}

// Выдать номера грузовиков на консоль

public void ShowComponents ( )

{

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

Console.WriteLine ("компонент номер " +

comp.Number.ToString ( ));

}

}

// Обработать событие склада

public void EvFromWarehouseHandler (object sender,

WarehouseEventArgs args)

{

leftRight= !leftRight;

IEnumerator inum= this.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

comp.LeftRight= leftRight;

}

}

}

// Интерфейс IRemObj удалённого объекта

public interface IRemObj

{

void AddLorry ( );

void RemoveLorry (int carrNumber);

void RemoveAllLorries ( );

ArrayList GetNumLorries ( );

void RunLorriers ( );

void StopLorriers ( );

void ShowComponents ( );

}

// Класс RemObj удалённого объекта

public class RemObj: Form, IRemObj

{

Warehouse leftWH; // Ссылки на объект левого склада

Warehouse rightWH; // Ссылки на объект правого склада

ContrlRegion region; // Ссылка на объект зоны контроля

Thread thread; // Ссылка но объект потока перерисовки

bool life; // Признок жизни потока перерисовки

LorryContainer lorryCont;// Ссылка на контейнер компонентов-

// грузовиков

public RemObj ( )

{

this.Text= "Server";

this.ClientSize= new Size (350, 130);

// Создать склады

// Создать объект левого склада

leftWH= new Warehouse(true, true);

leftWH.Location= new Point (10, 10);

leftWH.Size= new Size (30, 100);

leftWH.BackColor= Color.White;

this.Controls.Add (leftWH);

leftWH.Show ( );

// Создать объект правого склада

rightWH= new Warehouse (false, false);

rightWH.Location= new Point (200, 10);

rightWH.Size= new Size (30, 100);

rightWH.BackColor= Color.White;

this.Controls.Add (rightWH);

rightWH.Show ( );

// Создать область контроля

region= new ContrlRegion ( );

region.Location= new Point (100, 0);

region.Size= new Size (40, ClientSize.Height);

region.BackColor= Color.LightSkyBlue;

this.Controls.Add (region);

region.Show ( );

// Создать контейнер компонентов

lorryCont= new LorryContainer (leftWH, rightWH, region); //-----

// Создать поток перерисовки и запустить его

life= true;

thread= new Thread(new ThreadStart (ThrPaint));

thread.Start ( );

}

// Обработать нажатие кнопки пуска

public void RunLorriers ( )

{

lorryCont.RunLorries ( );

}

// Обработать нажатие кнопки останова

public void StopLorriers ( )

{

lorryCont.StopLorries ( );

}

// Обработать нажатие кнопки добавления грузовика

public void AddLorry ( )

{

lorryCont.AddLorry ( );

}

// Обработать нажатие кнопки удаления грузовика

public void RemoveLorry (int numSel)

{

lorryCont.RemoveLorry (numSel);

}

// Удалить все грузовики

public void RemoveAllLorries ( )

{

lorryCont.RemoveAllLorries ( );

}

// Получить номерв грузовиков

public ArrayList GetNumLorries ( )

{

return lorryCont.GetNumLorries ( );

}

// Показать номера компонентов

public void ShowComponents ( )

{

lorryCont.ShowComponents ( );

}

// Потоковая функция перерисовки

private void ThrPaint ( )

{

while (life)

{

Invalidate ( );

Thread.Sleep (150);

}

}

// Завершить поток перерисовки

public void Finish()

{

life= false; thread.Join ( );

}

// Обработать кнопку закрытия окна

protected override void OnClosed (EventArgs e)

{

base.OnClosed (e);

lorryCont.RemoveAllLorries ( );

Finish ( );

}

// Перерисовать область клиента прикладного окна

protected override void OnPaint (PaintEventArgs e)

{

base.OnPaint (e);

IEnumerator inum= lorryCont.Components.GetEnumerator ( );

while (inum.MoveNext ( ))

{

Lorry comp= (Lorry) inum.Current;

e.Graphics.DrawEllipse (new Pen (Color.Blue, 2),

comp.Point.X - 10, comp.Point.Y - 10, 20, 20);

e.Graphics.DrawString (comp.Number.ToString ( ), Font,

new SolidBrush (Color.Blue), comp.Point.X + 10,

comp.Point.Y + 10);

}

}

}

}