Задачка по дизайну, но имеет отношение к Java, поскольку реализовать надо на Java
Разрабатываю библиотеку/фреймворк для десериализации дерева объектов из бинарного формата
В общем , нужно отобразить некий бинарный формат на дерево POJO классов.
Сами классы имеют аннотации, чтобы парсер понимал размер поля и его смещение в бинарном файле.
каждый объект имеет заголовок, который одинаков по структуре,
и переменную часть, которая зависит от фактического типа объекта
если это моделировать наследованием — получается вот так
class BaseHeader {
@BaseOffset( offset = 20 )
@StaticSizeField( size = 2 )
private int length;
@StaticSizeField( size = 2 )
private int type;
@StaticSizeField( size = 3 )
private byte[] uuid = new byte[3];
// ... и еще куча разных свойств
public BaseHeader(BaseHeader copy) {
// "copy constructor"
setLength(copy.getLength() );
setType( copy.getType() ) ;
//... а можно это делать проще? не перечисляя каждую property
}
}
тип объектов, которые создаются, определяется в рантайме, из поля type в объекте BaseHeader
т.е. в рантайме мне нужно создать объект типа PriceRecord (или NameRecord, или любого другого),
но сначала нужно создать BaseHeader, и скопировать данные из него в конкретный инстанцированный объект
class PriceRecord extends BaseHeader {
@StaticSizeField( size = 20 )
private String priceQuoteId;
@StaticSizeField( size = 4 )
private Calendar expirationDate;
// ...
public PriceRecord() {}
public PriceRecord( BaseHeader copy ) {
super(copy)
}
}
объекты создаются фабрикой, примерно такого вида:
BaseHeader header= new BaseHeader();
TreeParser parser = new TreeParser();
parser.populateObject( header, bufferSource );
BaseHeader newObj = null;
if( header.getType() == 0x01 ) {
newObj = new PriceRecord(header);
parser.populateObject( newObj, bufferSource);
}
else if( header.getType() == 0x02 ) {
newObj = new NameRecord(header);
parser.populateObject( newObj, bufferSource);
}
else if( header.getType() == 0x04 ) {
newObj = new TicketRecord(header);
parser.populateObject( newObj, bufferSource);
}
else {
}
// и тд - можно запрятать в фабричный метод, но там та же суть
// на выходе - объект конкретного типа, а не Base
return newObj;
Проблема в том что каждый создаваемый класс, должен иметь конструктор, копирующий BaseHeader в поля своего базового класса
(что-то вроде "конструктор глубокого копирования" ), это неудобно и не очень красиво.
Как можно было бы сделать по другому?
классы — чисто POJO, никакого поведения у них нет
на выходе должен получиться List<BaseHeader> или List<Object> содержащий все инстанцированные объекты из файла
20.12.11 23:57: Перенесено модератором из 'Java' — по просьбе автора — Blazkowicz