Разработка приложения для организации работы турагентства
Скачать 306.71 Kb.
|
ArrayList public class Tour String title; String country; Integer price; Hotel hotel; Boolean isFire; public class Hotel String title; Integer stars; public class Request String tourTitle; Integer count; Integer totalCost; В результате анализа задачи были выбраны необходимые типы данных, выделены объекты для реализации в системе, определена их структура, графическое представление которой будет отображено в разделе 3. 3 Определение структуры программы Для графического представления спроектированной программы лучше всего использовать язык UML. UML — язык графического описания для объектного моделирования в области разработки программного обеспечения. UML является языком широкого профиля, это — открытый стандарт, использующий графические обозначения для создания абстрактной модели системы, называемой UML-моделью. UML был создан для определения, визуализации, проектирования и документирования, в основном, программных систем. Использование UML не ограничивается моделированием программного обеспечения. Его также используют для моделирования бизнес-процессов, системного проектирования организационных структур и баз данных. UML позволяет также разработчикам программного обеспечения достигнуть соглашения в графических обозначениях для представления общих понятий и сконцентрироваться на проектировании и архитектуре. Преимущества UML: − UML объектно-ориентирован; − UML позволяет описать систему практически со всех возможных точек зрения и разные аспекты поведения системы; − Диаграммы UML сравнительно просты для чтения после достаточно быстрого ознакомления с его синтаксисом; − UML расширяет и позволяет вводить собственные текстовые и графические стереотипы, что способствует его применению не только в сфере программной инженерии; UML получил широкое распространение и динамично развивается. Итак, структурируем выделенные объекты в системе. К описанию объектов выше добавим необходимые модификаторы, public class TravelAgency private ArrayList private ArrayList private ArrayList public class Tour private String title; private String country; private Integer price; private Hotel hotel; private Boolean isFire; public class Hotel private String title; private Integer stars; public class Request private String tourTitle; private Integer count; private Integer totalCost; Выделим дополнительный класс Main, содержащий точку входа в программу, и содержащий логику построения пользовательского интерфейса. В итоге структура приложения и взаимодействие классов будет иметь следующий вид, представленный на рис.1. Рис 1. –Структура приложения Каждый из разработанных классов, за исключением Main, содержит конструкторы, геттеры и сеттеры к полям и специальные методы для реализации требуемого функционала. В результате такого проектирования классы будут иметь следующий вид. На рис. ниже последовательно представлены классы разрабатываемой системы. Рис. 2 – Диаграмма класса TravelAgency Рис. 3 – Диаграмма класса Tour. Рис. 4 – Диаграмма класса Hotel Рис. 5. – Диаграмма класса Request В результате такого проектирования общая детальная структура приложения будет иметь следующий вид: Рис. 6. – Детализированная структура приложения 4 Разработка алгоритма Выделим требуемый функционал для реализации его в том или ином классе. Для классов Tour, Hotel, Request требуется, что о каждом его поле нужно иметь возможность получить информацию, изменить информацию. Для этого должны быть реализованы методы get и set. Аналогичным образом такие методы пишутся и в других классах. Для класса TourAgency геттеры и сеттеры реализуются аналогичным образом. Дополнительно, в соответствии с требованиями, реализуются следующие методы: Метод получения списка всех туров Методы получения туров по параметрам(страна, цена) Метод получения горящих туров Метод получения всех отелей Метод получения отеля по заданному количеству звезд Метод создания запроса на тур Метод получения всех запросов Создание запроса на тур подразумевает следующий процесс: метод получает в качестве параметра имя тура, желаемое количество путевок, создает экземпляр класса Request, передает туда эти параметры, добавляет экземпляр в список запросов. По одинаковому принципу строятся методы получения туров и отелей по параметрам. Передается нужный параметр, в цикле по нужному списку проверяется соответствие параметров заданному, в случае совпадения объект добавляется в возвращаемый список объектов. Методы, реализующие этот алгоритм, приведены в разделе 6. Обобщенная блок-схема алгоритма, характерная для методов получения списков отелей и туров, представлена ниже: Рис. 7 – Блок-схема метода покупки билета 5 Разработка пользовательского интерфейса Для приложения реализуется текстовый консольный интерфейс, заключающийся в выводе текста на экран и считывании символов – цифр пункта меню. Интерфейс имеет следующий вид: Турагенство Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход Интерфейс реализован в методе-точке входа в программу public static void main(String[] args) при помощи цикла и конструкции switch-case. Схема интерфейса имеет следующий вид: Рис. 8 – Схема интерфейса программы Диаграмма класса Main содержащая метод main() представлена ниже: Рис. 9 – Диаграмма класса Main 6 Написание кода Для реализации системы определим следующее: код на языке Java будет реализован по стандарту Java Bean с разделением кода на логические блоки – классы, содержащие бизнес-логику приложения и классы, отвечающие за построение интерфейса. Java Bean- JavaBeans — классы в языке Java, написанные по определённым правилам. Они используются для объединения нескольких объектов в один для удобной передачи данных. Спецификация Sun Microsystems определяет JavaBeans как повторно используемые программные компоненты, которыми можно управлять. JavaBeans обеспечивают основу для многократно используемых, встраиваемых и модульных компонентов ПО. Чтобы класс мог работать как bean, он должен соответствовать определённым соглашениям об именах методов, конструкторе и поведении. Эти соглашения дают возможность создания инструментов, которые могут использовать, замещать и соединять JavaBeans. Правила описания гласят: Класс должен иметь среди прочих конструктор без параметров, с модификатором доступа public. Такой конструктор позволяет инструментам создать объект без дополнительных сложностей с параметрами. Свойства класса должны быть доступны через get, set и другие методы (так называемые методы доступа), которые должны подчиняться стандартному соглашению об именах. Это легко позволяет инструментам автоматически определять и обновлять содержание bean’ов. Многие инструменты даже имеют специализированные редакторы для различных типов свойств. Класс должен быть сериализуем. Это даёт возможность надёжно сохранять, хранить и восстанавливать состояние bean независимым от платформы и виртуальной машины способом. Так как требования в основном изложены в виде соглашения, а не интерфейса, некоторые разработчики рассматривают JavaBeans, как Plain Old Java Objects, которые следуют определённым правилам именования. Все классы будут собраны в пакет JAR. Для разработки классов нужно определить типы и структуры данных, которыми будут объявлены свойства описанных объектов. Перейдем к рассмотрению наиболее содержательных участков кода. Начнем с рассмотрения метода main: Метод содержит объявление и создание экземпляра класса Scanner для считывания команд пользователя с клавиатуры. Далее происходит загрузка из файла на диске данных в систему и управление переходит в цикл, отвечающий за построение интерфейса. public static void main(String[] args) { sc = new Scanner(System.in); travelAgency = new TravelAgency(); try { loadFromBinaryFile(); } catch (Exception exc) { generateTestData(); } System.out.println("Турагенство"); main: while (true) { System.out.println("\nВведите номер команды"); System.out.println("" + "1 - Показать все туры\n" + "2 - Показать туры по стране\n" + "3 - Показать туры по цене\n" + "4 - Показать горящие туры\n" + "5 - Показать все отели\n" + "6 - Показать отели по количеству звезд\n" + "7 - Подать заявку на тур\n" + "8 - Показать все запросы\n" + "9 - Сохранить изменения\n" + "0 - Выход\n"); switch (sc.next()) { case "1": travelAgency.getTours().forEach(System.out::println); break; case "2": System.out.println("Введите страну"); travelAgency.getToursByCountry(sc.next()).forEach(System.out::println); break; case "3": System.out.println("Введите максимальную цену"); travelAgency.getToursByPrice(sc.nextInt()).forEach(System.out::println); break; case "4": travelAgency.getToursByFire().forEach(System.out::println); break; case "5": travelAgency.getHotels().forEach(System.out::println); break; case "6": System.out.println("Введите желаемое количество звезд"); travelAgency.getHotelsByStars(sc.nextInt()).forEach(System.out::println); break; case "7": System.out.println("Введите название тура, и желаемое количество путевок"); travelAgency.createRequest(sc.next(), sc.nextInt()); break; case "8": travelAgency.getRequests().forEach(System.out::println); break; case "9": saveToBinaryFile(); break; case "0": break main; default: System.out.println("Неверная команда"); } } } Поскольку система построения на списках ArrayList, то следует сказать следующее. При выводе информации на экран задействуется следующий механизм: у списка, возвращенного get-методом, вызывается метод forEach, который использует возможности Java 8, а именно Stream API и лямбда-выражения, что позволяет вывести список поэлементно при помощи одной строчки кода, не реализуя вывод с помощью цикла. Также для более удобного вывода информации на экран и удобно реализации этой функции были переопределены методы toString у всех классов. Класс TravelAgency: @Override public String toString() { final StringBuilder sb = new StringBuilder("\nTravelAgency{"); sb.append("\ntours=").append(tours); sb.append(", \nhotels=").append(hotels); sb.append(", \nrequests=").append(requests); sb.append('}'); return sb.toString(); } Класс Tour: @Override public String toString() { final StringBuilder sb = new StringBuilder("\nTour{"); sb.append("\ntitle='").append(title).append('\''); sb.append(", \ncountry='").append(country).append('\''); sb.append(", \nprice=").append(price); sb.append(", \nhotel=").append(hotel); sb.append(", \nisFire=").append(isFire); sb.append('}'); return sb.toString(); } Класс Hotel: @Override public String toString() { final StringBuilder sb = new StringBuilder("\nHotel{"); sb.append("title='").append(title).append('\''); sb.append(", stars=").append(stars); sb.append('}'); return sb.toString(); } Класс Request @Override public String toString() { final StringBuilder sb = new StringBuilder("\nRequest{"); sb.append("\ntourTitle='").append(tourTitle).append('\''); sb.append(", \ncount=").append(count); sb.append(", \ntotalCost=").append(totalCost); sb.append('}'); return sb.toString(); } Для построения строки используется класс StringBuilder, который отличается более высокой производительность по сравнению с классом String за счет того, что StringBuilder является изменяемым(mutable) объектов, в отличие от String. Для примера приведем методы, которые возвращают информацию по турам, принимая различные параметры: public ArrayList ArrayList for (Tour tour : this.tours) { if (tour.getCountry().equals(country)) { tours.add(tour); } } return tours; } public ArrayList ArrayList for (Tour tour : this.tours) { if (tour.getPrice() <= price) { tours.add(tour); } } return tours; } public ArrayList ArrayList for (Tour tour : this.tours) { if (tour.isFire()) { tours.add(tour); } } return tours; } Добавление в систему запроса происходит в следующем методе: public void createRequest(String tourTitle, Integer count) { requests.add(new Request(tourTitle, count, count * getTour(tourTitle).getPrice())); } Также для сохранения в файл и загрузки из него информации для соответствия стандарту Java Bean были реализованы методы в классе Main: private static void saveToBinaryFile() { FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream(BINARY_FILE_NAME); oos = new ObjectOutputStream(fos); oos.writeObject(travelAgency); } catch (IOException e) { System.err.println("Error while store to binary file"); // e.printStackTrace(); } finally { try { oos.flush(); oos.close(); } catch (IOException ex) { System.err.println("Error while trying close IO"); // ex.printStackTrace(); } } } private static void loadFromBinaryFile() { try { FileInputStream fis = new FileInputStream(BINARY_FILE_NAME); ObjectInputStream oin = new ObjectInputStream(fis); travelAgency = (TravelAgency) oin.readObject(); } catch (FileNotFoundException ex) { System.out.println("Generate test"); generateTestData(); } catch (IOException e) { e.printStackTrace(); System.out.println("Generate test"); generateTestData(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } Далее стоит отметить, что нерассмотренные методы в этом разделе содержатся в приложении с полным исходным кодом. Их рассмотрение было опущено по причине их аналогичной реализации и отсутствия отличительных особенностей. 7 Тестирование и отладка программы Тестирование работы программы проводилось при помощи специально разработанного метода, который генерирует некоторый набор данных. Генерация построена при помощи цикла и подставления значения счетчика в имена и значения характеристик. Это позволяет протестировать корректность работы программы, не затрачивая ресурсы и время на ручной ввод информации. Код этого метода приведен ниже: public static void generateTestData() { Random r = new Random(); for (int i = 0; i < 10; i++) { travelAgency.addHotel("Hotel_"+i,r.nextInt(4)+1); } for (int i = 0; i < 10; i++) { travelAgency.addTour("Tour_"+i,"Country_"+r.nextInt(10),r.nextInt(100000),travelAgency.getHotels().get(r.nextInt(travelAgency.getHotels().size())).getTitle(),r.nextBoolean()); } for (int i = 0; i < 5; i++) { travelAgency.createRequest(travelAgency.getTours().get(r.nextInt(travelAgency.getTours().size())).getTitle(),r.nextInt(4)+1); } } В результате генерируется следующий набор данных, выводящийся в консоль. На основе этих данных было произведено ручное тестирование, которое показало, что программа работает корректно. Консольный вывод при тестировании системы на работоспособность показан ниже: Турагенство Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 1 Tour{ title='Tour_0', country='Country_2', price=93861, hotel= Hotel{title='Hotel_9', stars=4}, isFire=true} Tour{ title='Tour_1', country='Country_3', price=95245, hotel= Hotel{title='Hotel_9', stars=4}, isFire=false} Tour{ title='Tour_2', country='Country_0', price=41680, hotel= Hotel{title='Hotel_7', stars=4}, isFire=true} Tour{ title='Tour_3', country='Country_8', price=76442, hotel= Hotel{title='Hotel_5', stars=1}, isFire=true} Tour{ title='Tour_4', country='Country_7', price=8449, hotel= Hotel{title='Hotel_4', stars=4}, isFire=false} Tour{ title='Tour_5', country='Country_1', price=26043, hotel= Hotel{title='Hotel_9', stars=4}, isFire=true} Tour{ title='Tour_6', country='Country_3', price=88937, hotel= Hotel{title='Hotel_1', stars=2}, isFire=true} Tour{ title='Tour_7', country='Country_9', price=26224, hotel= Hotel{title='Hotel_7', stars=4}, isFire=false} Tour{ title='Tour_8', country='Country_3', price=76520, hotel= Hotel{title='Hotel_7', stars=4}, isFire=false} Tour{ title='Tour_9', country='Country_3', price=40270, hotel= Hotel{title='Hotel_4', stars=4}, isFire=true} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 2 Введите страну Country_3 Tour{ title='Tour_1', country='Country_3', price=95245, hotel= Hotel{title='Hotel_9', stars=4}, isFire=false} Tour{ title='Tour_6', country='Country_3', price=88937, hotel= Hotel{title='Hotel_1', stars=2}, isFire=true} Tour{ title='Tour_8', country='Country_3', price=76520, hotel= Hotel{title='Hotel_7', stars=4}, isFire=false} Tour{ title='Tour_9', country='Country_3', price=40270, hotel= Hotel{title='Hotel_4', stars=4}, isFire=true} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 3 Введите максимальную цену 70000 Tour{ title='Tour_2', country='Country_0', price=41680, hotel= Hotel{title='Hotel_7', stars=4}, isFire=true} Tour{ title='Tour_4', country='Country_7', price=8449, hotel= Hotel{title='Hotel_4', stars=4}, isFire=false} Tour{ title='Tour_5', country='Country_1', price=26043, hotel= Hotel{title='Hotel_9', stars=4}, isFire=true} Tour{ title='Tour_7', country='Country_9', price=26224, hotel= Hotel{title='Hotel_7', stars=4}, isFire=false} Tour{ title='Tour_9', country='Country_3', price=40270, hotel= Hotel{title='Hotel_4', stars=4}, isFire=true} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 4 Tour{ title='Tour_0', country='Country_2', price=93861, hotel= Hotel{title='Hotel_9', stars=4}, isFire=true} Tour{ title='Tour_2', country='Country_0', price=41680, hotel= Hotel{title='Hotel_7', stars=4}, isFire=true} Tour{ title='Tour_3', country='Country_8', price=76442, hotel= Hotel{title='Hotel_5', stars=1}, isFire=true} Tour{ title='Tour_5', country='Country_1', price=26043, hotel= Hotel{title='Hotel_9', stars=4}, isFire=true} Tour{ title='Tour_6', country='Country_3', price=88937, hotel= Hotel{title='Hotel_1', stars=2}, isFire=true} Tour{ title='Tour_9', country='Country_3', price=40270, hotel= Hotel{title='Hotel_4', stars=4}, isFire=true} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 5 Hotel{title='Hotel_0', stars=1} Hotel{title='Hotel_1', stars=2} Hotel{title='Hotel_2', stars=4} Hotel{title='Hotel_3', stars=3} Hotel{title='Hotel_4', stars=4} Hotel{title='Hotel_5', stars=1} Hotel{title='Hotel_6', stars=3} Hotel{title='Hotel_7', stars=4} Hotel{title='Hotel_8', stars=2} Hotel{title='Hotel_9', stars=4} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 6 Введите желаемое количество звезд 4 Hotel{title='Hotel_2', stars=4} Hotel{title='Hotel_4', stars=4} Hotel{title='Hotel_7', stars=4} Hotel{title='Hotel_9', stars=4} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 8 Request{ tourTitle='Tour_2', count=2, totalCost=83360} Request{ tourTitle='Tour_6', count=3, totalCost=266811} Request{ tourTitle='Tour_7', count=2, totalCost=52448} Request{ tourTitle='Tour_4', count=3, totalCost=25347} Request{ tourTitle='Tour_9', count=2, totalCost=80540} Введите номер команды 1 - Показать все туры 2 - Показать туры по стране 3 - Показать туры по цене 4 - Показать горящие туры 5 - Показать все отели 6 - Показать отели по количеству звезд 7 - Подать заявку на тур 8 - Показать все запросы 9 - Сохранить изменения 0 - Выход 8 Программная документация При использовании программы следует учесть следующее: Программа распространяется вместе с файлом, в который сохраняется информация на диске. Если такового файла нет, то программа заполнит классы тестовым набором данных. Текстовый интерфейс рассчитан на ввод корректных данных На текущем этапе разработки программа не сообщает об ошибках при вводе, т.к. валидация, т.е. проверка вводимых данных не предусмотрена требованиями Информация о имеющихся методах сгенерирована утилитой Javadoc Скриншот документации представлен ниже: Рис.10 – Скриншот документации приложения Заключение После получения задания на разработку системы был проведен тщательный анализ его содержимого. Были выделены основные объекты в системе, их свойства, спрогнозированы и реализованы дополнительные объекты, за счет которых разработка системы была упрощена. Были применены подходящие типы и структуры данных, спроектированы, реализованы и протестированы алгоритмы, которые реализуют требуемый функционал программы в соответствии с заданием. Тестирование проведено на основе тестового корректного набора входных данных. Интерфейс приложения является текстовым, вся информация и ее считывание происходит в консоли. Программа удовлетворяет поставленным требованием и реализует возложенные на нее задачи. Перечень использованной литературы 1. Эккель, Б. Философия Java. Библиотека программиста /Б. Эккель – 4-е изд. – СПб.: Питер, 2009. – 640 с. [Текст] 2. Шилдт, Г. Java. Полное руководство /Г. Шилдт – 8-е изд.: пер. с англ. – М.: ООО «И.Д. Вильямс», 2012. – 1104 с. [Текст] 3. Спецификация языка Java [Электронный ресурс]/2014.– Режим доступа: http://java.sun.com/docs/books/jls, свободный. 4. Спецификация виртуальной машины Java [Электронный ресурс]/2014.– Режим доступа: http://java.sun.com/docs/books/jvms/, свободный. 5. Спецификация java.lang.Thread [Электронный ресурс]/2014.– Режим доступа: http://java.sun.com/javase/6/docs/api/java/lang/Thread.html, свободный. 6. Многопоточность в среде Java [Электронный ресурс]/2014.– Режим доступа: https://software.intel.com/ru-ru/articles/multi-threading-in-a-java-environment, свободный. 7. Уоллс, К. Spring в действии /Уоллс К. – пер. с англ. – М..: ДМК Пресс, 2013 - 752с.: [Текст] 8. Хемраджани, Анил. Гибкая разработка приложений на Java с помощью Spring, Hibernate и Eclipse./ Хемраджани, Анил.: пер. с англ. = М.: ООО «И. Д. Вильямс», 2008. – 352 с. [Текст] 9. Спецификация java.util.Concurrency [Электронный ресурс]/2014.– Режим доступа: http://java.sun.com/javase/6/docs/api/java/util/ Concurrency.html, свободный. 10. Гонсалвес, Э. Изучаем Java EE /Гонсалвес Э. – пер. с англ. – Спб..: Питер, 2014 – 640 с.: [Текст] 11 Шахгельдян, К.И. Объектно-ориентированное программирование.. [Текст]/ Шахгельдян К.И.: Влад., ВГУЭС, 2000 – 320с. 12 Балд, Т. Объектно-ориентированное программирование в действии. [Текст]/. Т.Бадд: Питер. 1997 – 430 с. 13 Буч, Г. Объектно-ориентированный анализ и проектирование. Addison-Wesley / Г. Буч. 1998. 14 Заварыкин, В.М. Основы информатики и вычислительной техники. [Текст] / Заварыкин В.М Житомирский В.Г., Лапчик М.П. — М.: Пр15 освещение, 2010 – 310 с. 16 Тассел, Д. Стиль, разработка, эффективность, отладка и испытание программ.[Текст] / Д. Ван Тассел — М.: Мир, 2011 – 530с. 17 Бондарев, В.М., Основы программирования. [Текст] / Бондарев В.М., Рублинецкий В.И., Качко Е.Г. —Харьков: Фолио, Ростов н/Д: Феникс, 2007 – 710 с.. 18 Элиенс, А. Принципы объектно-ориентированной разработки программ [Текст] / А. Элиенс. - 2-е издание. —М.: Издательский дом «Вильямс», 2002, 550 с. 19 Волкова, И. А. Системы программирования [Текст] / И. А. Волкова, И. Г. Головин, Л. Е. Карпов. — М.: Издательский отдел факультета ВМиК МГУ, 2009, 260 с. 20 Канер, Дж.. Тестирование программного обеспечения. [Текст] / Канер, Дж, Фолк, Е. К. Нгуен — М.: «DiaSoft», 2001, 370 с. Приложение Исходный код программы package TravelAgency; import java.io.Serializable; import java.util.ArrayList; public class TravelAgency implements Serializable { private static final long serialVersionUID = 3L; private ArrayList private ArrayList |