Java осень 2014 занятие 6
-
Upload
technopark -
Category
Education
-
view
165 -
download
1
description
Transcript of Java осень 2014 занятие 6
Углубленное программирование на
Java Лекция 2.3
«Инструменты»
Виталий Чибриков
План лекции
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
2
Pseudorandom number generator — алгоритм, порождающий последовательность чисел, элементы которой почти независимы друг от друга и подчиняются заданному распределению
Нет понятия случайного числа Есть последовательности чисел с заданным распределением
Random
3
Алгоритм случайности
4
Linear Congruential Pseudorandom Number Generator (See Donald Knuth, The Art of Computer Programming, Volume 3, Section 3.2.1.)
java.util.Random
modulus
increment
multiplier
seed
Параметры случайности
5
Source m (multiplier) a (increment) c
Borland C/C++ 232 22695477 1
glibc (used by GCC) 231 1103515245 12345
Borland Delphi, Virtual Pascal 232 134775813 1
Microsoft Visual/Quick C/C++ 232 214013 (343FD16) 2531011 (269EC316)
Microsoft Visual Basic (6 and earlier) 224 1140671485 (43FD43FD16)
12820163 (C39EC316)
C++11 231 − 1 16807 0
C++11's minstd_rand[9] 231 − 1 48271 0
MMIX by Donald Knuth 264 6364136223846793005 1442695040888963407
Java's java.util.Random, 248 25214903917 11
Math.random(); – вернет случайное число типа double от 0 до 1 При каждом запуске последовательность будет новой
Random rnd = new Random(1L); rnd.nextInt(100); – вернет случайное число от 0 до 99 При каждом запуске последовательность будет прежней
Random rnd = new Random(); rnd.nextInt(100); – вернет случайное число от 0 до 99 При каждом запуске последовательность будет новой
Random in java
6
…Sid Meier found that if a player lost too many 2-to-1 battles in a row, they would get frustrated. Instead of risking a player shutting the game down, Sid changed the math :o)
Субъективная случайность
7
Видео (Sid Meier GDC 2010):
http://www.youtube.com/watch?v=bY7aRJE-oOY
План лекции
8
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
Time & Date
9
Работа со временем
Работу со временем лучше перенести в TimeHelper
От миллисекунд до даты
UNIX или POSIX time – время с 1 января 1970 в секундах
Форматирование даты и времени для пользователей
Как хранить время в приложении и в базе
Подписка на таймер
TimeHelper
10
public class TimeHelper {
public static long getTimeInMs(){ Date date = new Date(); return date.getTime(); }
public static int getPOSIX(){ Date date = new Date(); int millisInSecond = 1000; return (int)(date.getTime() / millisInSecond); }
public static String getUserDateFull(Locale locale){ Date date = new Date(); DateFormat dateFormatter = DateFormat. getDateInstance(DateFormat.FULL, locale); return dateFormatter.format(date); } }
Timer
11
java.unil.Timer
java.unil.TimerTask
Порядок работы:
Создаем timer
Создаем класс унаследованный от TimerTask
Пишем в методе run() код, который будет выполнен по таймеру
Передаем в timer таск и время, через которое надо выполнить таск
Ждем положенное время
PROFIT!!!
Выключаем timer через timer.cancel();
Timer
12
int timeMs = 10000; TimeService.instance().start(); TimeService.instance().sheduleTask(new TimerTask(){
public void run() { System.out.append("Timer run!\n"); TimeService.instance().stop(); }
}, timeMs);
План лекции
13
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
I/O ― общение с внешними устройствами (файлы, принтеры, сеть и т.д.)
Поток ― объект который представляет источник или приемник данных
Поток основан на последовательности битов данных
I/O, потоки
14
InputStream
OutputStream
Основная задача ― читать байт за байтом из входного потока
Основные методы: abstract int read()
int read(byte[] b)
void mark(int readlimit)
void reset()
void close()
public abstract class InputStream
InputStream
15
Byte Streams
16
OutputStream
InputStream
PrintStream
FilterOutputStream BufferedOutputStream
DataOutputStream
FileInputStream
FilterInputStream
FileOutputStream
BufferedInputStream
DataInputStream
Переопределяет все методы InputStream вызывая методы поля in
Наследники этого класса могут менять работу потока в поле in
Decorator pattern
FilterInputStream
17
public class FilterInputStream extends InputStream
private InputStream in;
protected FilterInputStream(InputStream in){ this.in = in; }
Decorator
18
Decorator
19
Рассмотрим сериализованные java объекты, которые лежат в gzip архиве и которые мы хотим быстро прочесть.
Для начала откроем inputstream для файла:FileInputStream fis = new FileInputStream("/objects.gz");
Читать побитово для нас слишком долго -- буферизуем чтение:BufferedInputStream bis = new BufferedInputStream(fis);
Файл зазипован -- нам надо его разархивировать:GzipInputStream gis = new GzipInputStream(bis);
Теперь десиериализуем java объекты:ObjectInputStream ois = new ObjectInputStream(gis);
И, наконец, прочитаем:SomeObject someObject = (SomeObject) ois.readObject();
Character Streams
20
FileWriter
FileReader
Writer
Reader
BufferedWriter
OutputStreamWriter
PrintWriter
BufferedReader
InputStreamReader
Закрытие потоков
Для особождения ресурсов все потоки должны быть закрыты
BufferedReader br = null; try{ //code br = new BufferedReader(isr); //code } catch (Exception e){ System.err.println("Error: " + e.getMessage()); } finally { if(br != null){ try { br.close(); } catch (IOException e) { System.err.println("Error: " + e.getMessage()); } } }
21
План лекции
22
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
Процесс должен быть обратимым
Перевод объекта в формат данных удобный для хранения и передачи
Сериализация
23
Объект Метаданные
Примеры сериализации
Сериализация
24
Запись в бинарный файл
Запись в xml файл
Запись в json string
Запись blob в базу данных
Пересылка по сети между процессами
Описание объекта в стихах и пересылка почтовым голубем
interface Serializable
25
Обьект класса реализующего интерфейс Serializable можно сериализовать
Результат сериализации ― массив байт
Обычно объекты сериализуют в файл, в blob или в сетевой поток
Процесс сериализации:
Создание потока представляющего направление сериализации
Создание ObjectOutputStream для этого потока
Что будет сериализовано
26
Все поля сериализуемого объекта должны быть Serializable
Все поля будут сериализованы
Поля родительских классов реализующих Serializable будут сериализованы
Если родительский класс НЕ реализует Serializable, то при десериализации для него будет вызван конструктор по-умолчанию
Что НЕ будет сериализовано
27
Поле которое не надо сериализовать нужно пометить как transientprivate transient long time;
Статические поля сериализваны НЕ будут
При десериализации static и transient поля будут заполненызначениями по-умолчанию
Serialization Object
28
public class SerializationObject implements Serializable {
private String name; // name = Zoe private int age; // age = 31
… }
Запись в файл
29
SerializationObject object = new SerializationObject("Zoe", 31);
FileOutputStream fileOut = new FileOutputStream("test.bin");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(object);
out.close();
Десериализация
30
Чтение происходит в обратном порядке
родительские классы
классы переменных родительских классов
объекты родительских классов
значения переменных родительских классов
классы переменных
значения переменных
План лекции
31
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
Возможность проверить структуру объекта в runtime Возможность изменить поведение объекта в runtime
Reflection
32
Сериализация
Serializable – пустой интерфейс
Мы не написали ни строчки кода для сериализации объекта
Reflection разбирает объект и переводит его в массив байт
Используя Reflection можно
33
Получить список переменных класса
Получить список методов класса
Получить список конструкторов класса
Создать объект, вызвав его конструктор
Вызвать метод
Поменять область видимости переменной или метода
Минусы Reflection
34
Если задачу можно решить без reflection ―ее лучше решить без reflection
Потеря производительности
Не работает в окружении с повышенной безопасностью (applet-ы)
Разрушение ОО архитектуры
Основные методы класса Class
static Class<T> forName(String className) String getCanonicalName() Fields[] getField(String name) Class[] getInterfaces() Method[] getMethods() Constructor[] getConstructors()
java.lang.Class
35
― объект, который представляет в runtime данные о классе объектаClass
Как получить Class<?> объект
java.lang.Class
36
Class<?> clazz = object.getClass()
Class<?> clazz = className.class //в том числе для простых типов
Class<?> clazz = Class.forName(“java.io.Serializable”)
Class[] clases = clazz.getInterfaces()
java.lang.reflect.Member
37
java.lang.reflect.Member – интерфейс членов класса
Классы реализующие интерфейс Member
Field
Method
Constructor
ReflectionHelper
38
public static Object createIntance(String className){ try { return Class.forName(className).newInstance(); } catch (…){…} }
ReflectionHelper
39
public static void setFieldValue(Object object, String fieldName, String value){ try { Field field = object.getClass().getDeclaredField(fieldName); field.setAccessible(true);
if(field.getType().equals(String.class)){ field.set(object, value); } else if ( field.getType().equals(int.class)){ field.set(object, Integer.decode(value)); }
field.setAccessible(false); } catch(…){…} }
План лекции
40
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
XML Serialization
41
Данные объекта ― иерархически упорядоченные поля простых типов
XML документ ― иерархически упорядоченные тэги со строками
Имя переменной ― имя тэга
Значение переменной ― строковое значение тэга
Отличия XML
42
Занчительно проще редактировать
Значительно проще версионировать
Нет привязки к типу
Нет привязки к особенностям языка
Избыточна
Медленное чтение и запись
Стандартное средство обработки XML документов
Simple API for XML (SAX)
SAX parser
43
Обходит XML дерево
Посещает каждую ноду дерева
Для каждой ноды вызывает 3 callback-а
SAX parser
44
Порядок работы:
Читаем формат документа
Читаем первый тэг ― сообщаем приложению, что обработка начата
Читаем содержимое тэга
Сообщаем приложению содержимое тэга
Рекурсивно обращаемся ко всем вложенным тэгам
Сообщаем приложению, что обработка завершена
SAX parser методы
45
org.xml.sax.helpers.DefaultHandler
Методы для обработки тегов во время обхода документа:
startDocument()
startElement(…)
characters(…)
endElement(…)
endDocument()
Обход дерева
Десериализация XML
46
Задача:
Разработать XML формат для документа так чтобы
Можно было понять класс десериализуемого объекта
Тэг с именем переменной содержал
Атрибуты для восстановления переменной
Значение переменной
Записать ресурсы игры в выбранном формате
Простой XML документ
47
<class type=“main.SerializationObject”> <name>Zully</name> <age>23</age> </class>
startDocumentstartElement class
startElement nameendElement namestartElement ageendElement age
endElement classendDocument
Порядок обработки SAX парсером:
Handler
public class SaxEmptyHandler extends DefaultHandler { private static String CLASSNAME = "class"; private Object object; private String element;
public void startElement(String uri, String localName, String qName, Attributes attributes) { … }
public void endElement(String uri, String localName, String qName) { ... }
public void characters(char ch[], int start, int length) { … } }
48
Используем Reflection
public void startElement(String uri, String localName, String qName, Attributes attributes) { if(qName != CLASSNAME){ element = qName; } else { String className = attributes.getValue(0); System.out.println("Class name: " + className); object = ReflectionHelper.createIntance(className); } }
public void endElement(String uri, String localName, String qName) { element = null; }
public void characters(char ch[], int start, int length) { if(element != null){ String value = new String(ch, start, length); System.out.println(element + " = " + value); ReflectionHelper.setFieldValue(object, element, value); } }
49
DOM parser
50
javax.xml.parsers.DocumentBuilderFactory javax.xml.parsers.DocumentBuilder org.w3c.dom.Document
File fXmlFile = new File(“test.xml”); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(fXmlFile);
Document Object Model Сначала прочитаем весь XML, потом обойдем все ноды
SAX & DOM сравнение
51
SAX parser DOM parser
SAX (Simple API for XML) парсер не создает никакой внутренней структуры. Вместо этого, он берет все вхождения компонентов во входящем документе в виде событий (events) и говорит клиенту что он читает, поскольку он читает через входящий документ.
DOM (Document Object Model) парсер создает древовидную структуру в памяти из входящего документа и лишь потом ждет запросов от клиента.
SAX парсер всегда отдает клиенту лишь куски документа. Всегда отдает клиенту целый документ, независимо от того, сколько в действительности необходимо пользователю.
Менее требователен к ресурсам и занимаемому свободному месту в случае использования больших входящих документов (потому что он не создает внутренней структуры). Также он запускается быстрее и более легок в изучении, чем DOM парсер.
Имеет богатый функционал. Создает DOM-дерево в памяти и позволяет доступаться к любой части документа, а также модифицировать его. Но он не рационально распоряжается свободным местом в случае использования огромных документов.
Используйте в следующих случаях: ▪ Входящий документ слишком велик для доступной
памяти ▪ Когда необходимо прочитать лишь небольшой
участок документа. ▪ Используя SAX, вы используете меньшее количество
памяти и производите меньше динамических резерваций памяти.
Используйте в следующих случаях: ▪ Вашему приложению необходимо иметь доступ к
различным частям документа и использование собственной структуры столь же сложно, как и использование дерева DOM.
▪ Вашему приложению необходимо изменять дерево очень часто и данные должны быть сохранены на определенный период времени.
План лекции
52
1. Random
2. Time и Date
3. I/O streams
4. Serialization
5. Reflection
6. SAX & DOM
7. Resource System
Resource
53
― интерфейс для всех объектов со статическими данными
Конкретный ресурс можно собрать на основе XML документа
Ресурс одного типа может быть описан несколькими XML документами
Уникальность игрового ресурса ― путь к его XML файлу
XML документы для ресурсов создают дизайнеры
Все параметры игры должны быть в ресурсах
Resource
Resource Systen
54
Ресурсная система
XML файлы с описанием игровых объектов
Инструменты для редактирования XML файлов
Инструменты для создания игровых объектов по ресурсам
Resource Systen
55
В Allods Online
3 года разработки
> 200 000 ресурсов
Загрузка всех ресурсов примерно 30 минут
На разработке ресурсной системы 2 программиста
На разработке редакторов 3 программиста
Ресурсы создавали > 10 дизайнеров
ResourceFactory
56
ResourceFactory – фабрика ресурсов
Возвращает объект ресурса по пути к XML файлу
ДЗ
57
Вынести все параметры в XML файлы
Создать class ResourceFactory (singleton)
GMResource resource = (GMResource) ResourceFactory.instance().get(“./data/GMConfig.xml”)
Создать interface Resource и class GMResource
ResourceSystem *
58
Загрузка всех ресурсов при старте сервера
Используем VFS.instance().getIterator(“./data”)
Все ресурсы храним в директории ./data
Обходим все файлы и создаем все ресурсы
Ресурсы храним в Map<String, Resource>
Спасибо за внимание
Виталий Чибриков [email protected]