java осень 2014 занятие 6

59
Углубленное программирование на Java Лекция 2.3 «Инструменты» Виталий Чибриков

Upload: technopark

Post on 25-Jun-2015

163 views

Category:

Education


1 download

DESCRIPTION

Java осень 2014 занятие 6

TRANSCRIPT

Page 1: Java осень 2014 занятие 6

Углубленное программирование на

Java Лекция 2.3

«Инструменты»

Виталий Чибриков

Page 2: Java осень 2014 занятие 6

План лекции

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

2

Page 3: Java осень 2014 занятие 6

Pseudorandom number generator — алгоритм, порождающий последовательность чисел, элементы которой почти независимы друг от друга и подчиняются заданному распределению

Нет понятия случайного числа Есть последовательности чисел с заданным распределением

Random

3

Page 4: Java осень 2014 занятие 6

Алгоритм случайности

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

Page 5: Java осень 2014 занятие 6

Параметры случайности

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

Page 6: Java осень 2014 занятие 6

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

Page 7: Java осень 2014 занятие 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

Page 8: Java осень 2014 занятие 6

План лекции

8

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

Page 9: Java осень 2014 занятие 6

Time & Date

9

Работа со временем

Работу со временем лучше перенести в TimeHelper

От миллисекунд до даты

UNIX или POSIX time – время с 1 января 1970 в секундах

Форматирование даты и времени для пользователей

Как хранить время в приложении и в базе

Подписка на таймер

Page 10: Java осень 2014 занятие 6

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); } }

Page 11: Java осень 2014 занятие 6

Timer

11

java.unil.Timer

java.unil.TimerTask

Порядок работы:

Создаем timer

Создаем класс унаследованный от TimerTask

Пишем в методе run() код, который будет выполнен по таймеру

Передаем в timer таск и время, через которое надо выполнить таск

Ждем положенное время

PROFIT!!!

Выключаем timer через timer.cancel();

Page 12: Java осень 2014 занятие 6

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);

Page 13: Java осень 2014 занятие 6

План лекции

13

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

Page 14: Java осень 2014 занятие 6

I/O ― общение с внешними устройствами (файлы, принтеры, сеть и т.д.)

Поток ― объект который представляет источник или приемник данных

Поток основан на последовательности битов данных

I/O, потоки

14

InputStream

OutputStream

Page 15: Java осень 2014 занятие 6

Основная задача ― читать байт за байтом из входного потока

Основные методы: abstract int read()

int read(byte[] b)

void mark(int readlimit)

void reset()

void close()

public abstract class InputStream

InputStream

15

Page 16: Java осень 2014 занятие 6

Byte Streams

16

OutputStream

InputStream

PrintStream

FilterOutputStream BufferedOutputStream

DataOutputStream

FileInputStream

FilterInputStream

FileOutputStream

BufferedInputStream

DataInputStream

Page 17: Java осень 2014 занятие 6

Переопределяет все методы InputStream вызывая методы поля in

Наследники этого класса могут менять работу потока в поле in

Decorator pattern

FilterInputStream

17

public class FilterInputStream extends InputStream

private InputStream in;

protected FilterInputStream(InputStream in){ this.in = in; }

Page 18: Java осень 2014 занятие 6

Decorator

18

Page 19: Java осень 2014 занятие 6

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();

Page 20: Java осень 2014 занятие 6

Character Streams

20

FileWriter

FileReader

Writer

Reader

BufferedWriter

OutputStreamWriter

PrintWriter

BufferedReader

InputStreamReader

Page 21: Java осень 2014 занятие 6

Закрытие потоков

Для особождения ресурсов все потоки должны быть закрыты

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

Page 22: Java осень 2014 занятие 6

План лекции

22

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

Page 23: Java осень 2014 занятие 6

Процесс должен быть обратимым

Перевод объекта в формат данных удобный для хранения и передачи

Сериализация

23

Объект Метаданные

Page 24: Java осень 2014 занятие 6

Примеры сериализации

Сериализация

24

Запись в бинарный файл

Запись в xml файл

Запись в json string

Запись blob в базу данных

Пересылка по сети между процессами

Описание объекта в стихах и пересылка почтовым голубем

Page 25: Java осень 2014 занятие 6

interface Serializable

25

Обьект класса реализующего интерфейс Serializable можно сериализовать

Результат сериализации ― массив байт

Обычно объекты сериализуют в файл, в blob или в сетевой поток

Процесс сериализации:

Создание потока представляющего направление сериализации

Создание ObjectOutputStream для этого потока

Page 26: Java осень 2014 занятие 6

Что будет сериализовано

26

Все поля сериализуемого объекта должны быть Serializable

Все поля будут сериализованы

Поля родительских классов реализующих Serializable будут сериализованы

Если родительский класс НЕ реализует Serializable, то при десериализации для него будет вызван конструктор по-умолчанию

Page 27: Java осень 2014 занятие 6

Что НЕ будет сериализовано

27

Поле которое не надо сериализовать нужно пометить как transientprivate transient long time;

Статические поля сериализваны НЕ будут

При десериализации static и transient поля будут заполненызначениями по-умолчанию

Page 28: Java осень 2014 занятие 6

Serialization Object

28

public class SerializationObject implements Serializable {

private String name; // name = Zoe private int age; // age = 31

… }

Page 29: Java осень 2014 занятие 6

Запись в файл

29

SerializationObject object = new SerializationObject("Zoe", 31);

FileOutputStream fileOut = new FileOutputStream("test.bin");

ObjectOutputStream out = new ObjectOutputStream(fileOut);

out.writeObject(object);

out.close();

Page 30: Java осень 2014 занятие 6

Десериализация

30

Чтение происходит в обратном порядке

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

классы переменных родительских классов

объекты родительских классов

значения переменных родительских классов

классы переменных

значения переменных

Page 31: Java осень 2014 занятие 6

План лекции

31

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

Page 32: Java осень 2014 занятие 6

Возможность проверить структуру объекта в runtime Возможность изменить поведение объекта в runtime

Reflection

32

Сериализация

Serializable – пустой интерфейс

Мы не написали ни строчки кода для сериализации объекта

Reflection разбирает объект и переводит его в массив байт

Page 33: Java осень 2014 занятие 6

Используя Reflection можно

33

Получить список переменных класса

Получить список методов класса

Получить список конструкторов класса

Создать объект, вызвав его конструктор

Вызвать метод

Поменять область видимости переменной или метода

Page 34: Java осень 2014 занятие 6

Минусы Reflection

34

Если задачу можно решить без reflection ―ее лучше решить без reflection

Потеря производительности

Не работает в окружении с повышенной безопасностью (applet-ы)

Разрушение ОО архитектуры

Page 35: Java осень 2014 занятие 6

Основные методы класса 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

Page 36: Java осень 2014 занятие 6

Как получить Class<?> объект

java.lang.Class

36

Class<?> clazz = object.getClass()

Class<?> clazz = className.class //в том числе для простых типов

Class<?> clazz = Class.forName(“java.io.Serializable”)

Class[] clases = clazz.getInterfaces() 

Page 37: Java осень 2014 занятие 6

java.lang.reflect.Member

37

java.lang.reflect.Member – интерфейс членов класса

Классы реализующие интерфейс Member

Field

Method

Constructor

Page 38: Java осень 2014 занятие 6

ReflectionHelper

38

public static Object createIntance(String className){ try { return Class.forName(className).newInstance(); } catch (…){…} }

Page 39: Java осень 2014 занятие 6

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(…){…} }

Page 40: Java осень 2014 занятие 6

План лекции

40

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

Page 41: Java осень 2014 занятие 6

XML Serialization

41

Данные объекта ― иерархически упорядоченные поля простых типов

XML документ ― иерархически упорядоченные тэги со строками

Имя переменной ― имя тэга

Значение переменной ― строковое значение тэга

Page 42: Java осень 2014 занятие 6

Отличия XML

42

Занчительно проще редактировать

Значительно проще версионировать

Нет привязки к типу

Нет привязки к особенностям языка

Избыточна

Медленное чтение и запись

Page 43: Java осень 2014 занятие 6

Стандартное средство обработки XML документов

Simple API for XML (SAX)

SAX parser

43

Обходит XML дерево

Посещает каждую ноду дерева

Для каждой ноды вызывает 3 callback-а

Page 44: Java осень 2014 занятие 6

SAX parser

44

Порядок работы:

Читаем формат документа

Читаем первый тэг ― сообщаем приложению, что обработка начата

Читаем содержимое тэга

Сообщаем приложению содержимое тэга

Рекурсивно обращаемся ко всем вложенным тэгам

Сообщаем приложению, что обработка завершена

Page 45: Java осень 2014 занятие 6

SAX parser методы

45

org.xml.sax.helpers.DefaultHandler

Методы для обработки тегов во время обхода документа:

startDocument()

startElement(…)

characters(…)

endElement(…)

endDocument()

Обход дерева

Page 46: Java осень 2014 занятие 6

Десериализация XML

46

Задача:

Разработать XML формат для документа так чтобы

Можно было понять класс десериализуемого объекта

Тэг с именем переменной содержал

Атрибуты для восстановления переменной

Значение переменной

Записать ресурсы игры в выбранном формате

Page 47: Java осень 2014 занятие 6

Простой XML документ

47

<class type=“main.SerializationObject”> <name>Zully</name> <age>23</age> </class>

startDocumentstartElement class

startElement nameendElement namestartElement ageendElement age

endElement classendDocument

Порядок обработки SAX парсером:

Page 48: Java осень 2014 занятие 6

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

Page 49: Java осень 2014 занятие 6

Используем 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

Page 50: Java осень 2014 занятие 6

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, потом обойдем все ноды

Page 51: Java осень 2014 занятие 6

SAX & DOM сравнение

51

SAX parser DOM parser

SAX (Simple API for XML)  парсер не создает никакой внутренней структуры. Вместо этого, он берет все вхождения компонентов во входящем документе в виде событий (events) и говорит клиенту что он читает, поскольку он читает через входящий документ.

DOM (Document Object Model) парсер создает древовидную структуру в памяти из входящего документа и лишь потом ждет запросов от клиента.

SAX парсер  всегда отдает клиенту лишь куски документа. Всегда отдает клиенту целый документ, независимо от того, сколько в действительности необходимо пользователю.

Менее требователен к ресурсам и занимаемому свободному месту в случае использования больших входящих документов (потому что он не создает внутренней структуры). Также он запускается быстрее и более легок в изучении, чем DOM парсер.

Имеет богатый функционал. Создает DOM-дерево в памяти и позволяет доступаться к любой части документа, а также модифицировать его. Но он не рационально распоряжается свободным местом в случае использования огромных документов.

Используйте  в следующих случаях: ▪ Входящий документ слишком велик для доступной

памяти ▪ Когда необходимо прочитать лишь небольшой

участок документа. ▪ Используя SAX, вы используете меньшее количество

памяти и производите меньше динамических резерваций памяти.

Используйте в следующих случаях: ▪ Вашему приложению необходимо иметь доступ к

различным частям документа и использование собственной структуры столь же сложно, как и использование дерева DOM.

▪ Вашему приложению необходимо изменять дерево очень часто и данные должны быть сохранены на определенный период времени.

Page 52: Java осень 2014 занятие 6

План лекции

52

1. Random

2. Time и Date

3. I/O streams

4. Serialization

5. Reflection

6. SAX & DOM

7. Resource System

Page 53: Java осень 2014 занятие 6

Resource

53

― интерфейс для всех объектов со статическими данными

Конкретный ресурс можно собрать на основе XML документа

Ресурс одного типа может быть описан несколькими XML документами

Уникальность игрового ресурса ― путь к его XML файлу

XML документы для ресурсов создают дизайнеры

Все параметры игры должны быть в ресурсах

Resource

Page 54: Java осень 2014 занятие 6

Resource Systen

54

Ресурсная система

XML файлы с описанием игровых объектов

Инструменты для редактирования XML файлов

Инструменты для создания игровых объектов по ресурсам

Page 55: Java осень 2014 занятие 6

Resource Systen

55

В Allods Online

3 года разработки

> 200 000 ресурсов

Загрузка всех ресурсов примерно 30 минут

На разработке ресурсной системы 2 программиста

На разработке редакторов 3 программиста

Ресурсы создавали > 10 дизайнеров

Page 56: Java осень 2014 занятие 6

ResourceFactory

56

ResourceFactory – фабрика ресурсов

Возвращает объект ресурса по пути к XML файлу

Page 57: Java осень 2014 занятие 6

ДЗ

57

Вынести все параметры в XML файлы

Создать class ResourceFactory (singleton)

GMResource resource = (GMResource) ResourceFactory.instance().get(“./data/GMConfig.xml”)

Создать interface Resource и class GMResource

Page 58: Java осень 2014 занятие 6

ResourceSystem *

58

Загрузка всех ресурсов при старте сервера

Используем VFS.instance().getIterator(“./data”)

Все ресурсы храним в директории ./data

Обходим все файлы и создаем все ресурсы

Ресурсы храним в Map<String, Resource>

Page 59: Java осень 2014 занятие 6

Спасибо за внимание

Виталий Чибриков [email protected]