Розглянемо фізичні дані, з якими ми будемо оперувати.
По-перше, інформація, що надходить. Її можна інкапсулювати у єдиний клас – WeatherData з наступними полями:
номер модуля (moduleNumber);
температура (temperature);
атмосферний тиск(preasure);
сила вітру(windPower);
напрямок вітру(windDirection);
контрольна сума(src);
Також інкапсулюємо у класі методи для оперування з цими полями.
По-друге, фізична модель модуля збору інформації може бути уособлена в класі Module. З наступними молями:
номер модуля (moduleNumber);
опис модуля (moduleDescription);
інформація про погоду, що передається (weatherData).
До того ж необхідні методи, що характеризуватимуть роботу модуля:
sendModuleNumber() – посилає поточному модулю запит на відповідь – інформацію від погодних датчиків.
createWeatherData(byte [] recivedBytes) – утворення об’єкта класу WeatherData; параметри byte [] recivedBytes – набір байтів, який є відповіддю поточного модуля на запит від керуючої програми.
Також для роботи будь-якої програми необхіден набір утилітарних класів, які будуть допомідними під час виконання програми (пакет util).
|
|
Розглянемо їх:
Transmitter – клас, що відповідає за передачу даних. Він характеризується наступними полями:
OutputStream out – вихідний поток, куди вестиметься передача;
int PACKAGE_SIZE – розмір вихідного буфера для передачі даних.
sendBytes (byte [] byte01) – метод для відправки пакету байтів до вихідного потока, параметри byte [] byte01 – набір вихідних байтів для передачі.
Receiver – клас, що відповідає за прийом даних. Він характеризується наступними полями:
InputStream out – вхідний поток, звідки вестиметься передача;
int PACKAGE_SIZE – розмір вхідного буфера для прийому даних.
byte [] readData() – метод для прийому пакету байтів до вхідного потока.
Слід також зазначити, що клас Receiver реалізує інтерфейс Runnable, це означає, цо від призначений для щапуску у окремому потоці.
Класи Transmitter та Receiver побудовані по шаблону Singletone, це означає, що що присутній лише єдиний екземпляр класу. І дійсно: непотрібно тримати у системі два класи для передачі або прийому даних, аби уникнути помилок при роботі програми.
Наприклад для реалізації цього шаблону застосовується:
private Receiver() { }
public static Receiver getInstanse()
{if (receiver!= null) return receiver;
receiver = new Receiver();
return receiver;}
Скільки б раз ми не викликали метод getInstanse(), ми працюватимемо з одним й тим самим екземпляром класу.
Розробка інших утилітарних класів. При роботі програми, що проектується можливі виникнення двох умовних типів помилок:
перша група – некритична, тобто помилка, що не заважатиме нормальному ходу виконання програми. Очевидно дії при її виникнені мають носити суто інформаційний характер для користувача; наприклад «помилка рпи передачі даних».
|
|
друга група – критичні помилки, при виникненні яких подальша робота програми є неможлиивою, та необхідно робити терміновий вихід з програми; наприклад «lpt-порт не знайдено», або «помилка при спробі відкрити порт на запис».
Для зручної обробки цих помилок у класі BadEvent передбачено два статичних методи:
public static void throwCriticalEvent(Exception ex, Component sourse, String message)
public static void throwNonCriticalEvent(Exception ex, Component sourse, String message)
параметри: Exception ex – клас помилки, Component sourse – джерело помилки, String message – повідомлення про помилку.
У класі Helper інкапсульовані допоміжні методи для роботи програми, а також методі, призначені для роботи програми у тестовому режимі.
public static byte[] integerToBytes(int number) – перевід числа до послідовності бітів, придатних для передачі до lpt-порту при даному протоколі передачі; параметри int number – число для передачі.
public static byte [] testStringIntoBytes(int moduleNumber) – перевід тестової строки, взятої з файлу для імітації сигналів, отриманої від модуля.
Також він містить константи для підстройки програми під час роботи.
Організація обміну даними по розробленому протоколу