Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 09.11.2012, 22:42
terbooter вне форума Посмотреть профиль Отправить личное сообщение для terbooter Найти все сообщения от terbooter
  № 21  
Ответить с цитированием
terbooter

Регистрация: Oct 2006
Адрес: Novosibirsk-Kaliningrad
Сообщений: 1,278
Отправить сообщение для terbooter с помощью ICQ Отправить сообщение для terbooter с помощью Skype™
Интересная задачка.
Я бы сделал так.

Допустим есть две фигуры многоугольник и линия. Все данные (внутренний RAW формат)
храним в классах Polygon и Line, которые наследуются от RawObject и являются обычной структурой данных
Код AS3:
class RawObject{
     public var x:int;
     public var y:int;
     ...
}
class Line extends RawObject{
     public var lineThickness:int=0;
     public var length:int=0;
}
class Polygon extends RawObject{
     public var lineThickness:int=0;
     public var vertexCount:int=0;
}
Классы отображения на экране: ScreenPolygon и ScreenLine наследуются от ScreenObject
Код AS3:
class ScreenObject extends Sprite{
    public function draw():void; 
    public function getRawObject():RawObject;
    public function setRawObject():void;
}
Таким образом экономится память, так как можно отрисовывать графику только ту, которая находится в видимой области.
Не нужные спрайты убирать с экрана, но данные обо всех объектах будут в памяти.

Сериализатор/десериализатор должен быть отдельно от объекта, без свитча не обойтись, но разнести все по отдельным классам
Код AS3:
class Format1Serializer implements ISerializer{
     public serialize(object:RawObject):XML{
            var concreateSerializer:ISerializer;
            if(object is Line){
                 concreateSerializer = new Format1LineSerializer(); //Тут нужен пул сериалайзеров 
            }else if (object is Polygon){
                 concreateSerializer = new Format1PolygonSerializer();
            } 
            return concreateSerializer.serialize();
     }
}
В готовом XML с описанием объекта должна быть инфа о формате и о типе объекта, чтобы десериализовать.


Последний раз редактировалось terbooter; 09.11.2012 в 23:52.
Старый 09.11.2012, 23:07
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 22  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
//Тут нужен пул сериалайзеров
Да зачем пул. Просто создаем вначале по сериализатору на каждый тип и всё.
А если сериализаторы решили в конструктор принимать объект и не хотят работать с другим - то пул применить и не получится.

Цитата:
Сериализатор и десериализатор должен быть отдельно, без свитча не обойтись, но разнести все по отдельным классам
Ничего такого он Вам не должен. Если удобно оъединить сериализатор и десериализатор конкретного типа в один класс - почему нет?

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

Т.е. мы хотим отделить сериализацию от компонентов, но...
... по поводу оператора is:
Эта штука подкидывает ошибок при рефакторинге - компилятор не скажет, если этот класс уже не является RawObject, можно так же огрести при выносе промежуточных подклассов.

Стандартное решение здесь - это паттерн Посетитель.
Но это плохое решение - паттерн слишком многословный и слишком ограничивает - шаг вправо/влево от области применения и созданные им проблемы затмевают всякий выигрыш (за всю историю один раз использовал и считаю, что можно было этого не делать)

Можно сделать промежуточное решение (лучше is только тем что при рефакторинге меньше проблем подкидывает, заявить что его надо прямо использовать я не готов, но всё же):
Код AS3:
class RawObject{
     public var x:int;
     public var y:int;
     ...
     public function get asLine():Line { return null };
     public function get asPolygon():Polygon { return null };
}
class Line extends RawObject{
     public var lineThickness:int=0;
     public var length:int=0;
     override public function get asLine():Line { return this; };
}
class Polygon extends RawObject{
     public var lineThickness:int=0;
     public var vertexCount:int=0;
     override pulbic function get asPolygon():Polygon { return this; };
}
И вместо is Line пишем .asLine != null.
Отличите от is только в том, что если класс исчезнет из иерархии этих объектов при рефакторинге, и некоторых других рефакторинговых претурбациях компилятор потыкает на места, которые было бы неплохо поправить. Только и всего.
Плюс понятно по каким сущностям ходить в свитче - это просто списко полей, начинающихся на as у RawObject. С is по каким классам свитчить не так очевидно.


Последний раз редактировалось expl; 09.11.2012 в 23:27.
Старый 09.11.2012, 23:15
terbooter вне форума Посмотреть профиль Отправить личное сообщение для terbooter Найти все сообщения от terbooter
  № 23  
Ответить с цитированием
terbooter

Регистрация: Oct 2006
Адрес: Novosibirsk-Kaliningrad
Сообщений: 1,278
Отправить сообщение для terbooter с помощью ICQ Отправить сообщение для terbooter с помощью Skype™
Что касается инспектора свойств, то я сделал бы так.
Каждое свойство загнать в интерфейс. Обычно бывает много одинаковых свойств, поэтому можно несколько свойств помещать в один интерфейс расширяя интерфейсы. Тут зависит от того какие будут у вас объекты.
Само же свойство сделать отдельным объектом
Код AS3:
class Property{
    public function Property(contextObject:RawObject){
    }
 
    public var name:String;
    public var description:String;
 
    public function setPropertyValue(value:String){
    }
    public function getPropertyValue():String{
    }
 
}
 
interface IVertexCount {
    function getVertexCount():int;
    function setVertexCount(value:int):void;
}
 
class VertexCountProperty{
   public function VertexCountProperty(contextObject:RawObject){
       super(contextObject);
       name = "Число вершин";
       description = "Задайте количество вершин";
   }
 
    override public function setPropertyValue(value:String){
            (contextObject as IVertexCount).setVertexCount(parseInt(value)); 
    }
    override public function getPropertyValue():String{
            (contextObject as IVertexCount).getVertexCount().toString(); 
    }
 
}
Классу RawObject добавим список свойств которые можно изменять
public var properties:Array;

Если выделить на экране ScreenObject, то инспектор свойств получит ссылку на этот объект, возьмет из него RawObject в котором хранятся все доступные для изменения свойства. Пробегаем массив. Строим формочку для отображения свойств.
Когда юзер изменил свойство и нажал "ок", то у соответствующего свойства вызываем setPropertyValue, а у экранного объекта вызываем draw(), чтобы обновить графическое представление изменившейся модели

Добавлено через 5 минут
expl, я отредактировал пост. PolygonSerializer заменил на Format1PolygonSerializer. У меня мысль тут такая: Количество классов сериалайзеров = количество фигур * ко-во форматов

Старый 09.11.2012, 23:39
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 24  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
С точки зрения Adobe нет ничего плохого в том' что объект умеет себя сериализовать и десериализовать. Примеры из API плеера: методы toString и toJSON, интерфейс IExternalizable.
Насчет архитектуры я бы посоветовал обратить внимание на пакет spark.primitives из Flex framework. Отличная структура и расширяемость.
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 09.11.2012, 23:43
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 25  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
С точки зрения Adobe нет ничего плохого в том' что объект умеет себя сериализовать и десериализовать. Примеры из API плеера: методы toString и toJSON, интерфейс IExternalizable.
Насчет архитектуры я бы посоветовал обратить внимание на пакет spark.primitives из Flex framework. Отличная структура и расширяемость.
Да, в этом не только нет ничего плохого, это больше соотвествует духу ООП - полиморфизму. Но это работает только в одну сторону. В другую надо сделать свитч, хотябы чтобы создать объект правильного типа, у которого потом вызывать deserialize(data)

P.S. Свитч, конечно, заменяется более расширяемой структурой - регистром типов. Например, в сериализаторе AMF - это регистрация типов по registerClassAlias. Было б ради чего.

Старый 09.11.2012, 23:49
alatar вне форума Посмотреть профиль Отправить личное сообщение для alatar Найти все сообщения от alatar
  № 26  
Ответить с цитированием
alatar
 
Аватар для alatar

блогер
Регистрация: Dec 2008
Адрес: Israel, Natanya
Сообщений: 4,740
Записей в блоге: 11
Можно и без switch, если сериализованный объект будет содержать qualified class name или алиас (соответственно в приложении должен быть ассоциативный массив с алиасами в качестве ключей и классами в качестве значений).
__________________
משיח לא בא
משיח גם לא מטלפן

Старый 09.11.2012, 23:54
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 27  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
expl, я отредактировал пост. PolygonSerializer заменил на Format1PolygonSerializer. У меня мысль тут такая: Количество классов сериалайзеров = количество фигур * ко-во форматов
Сути дела это, вроде, не меняет.

Цитата:
Что касается инспектора свойств, то я сделал бы так.
Каждое свойство загнать в интерфейс. Обычно бывает много одинаковых свойств, поэтому можно несколько свойств помещать в один интерфейс расширяя интерфейсы. Тут зависит от того какие будут у вас объекты.
Не перебор ли? Да и приведения типов не радуют.
Не проще ли сделать прямо в объекте нужного типа простые геттеры и сеттеры, которых нет у других типов.
Сделать для всех метод getEditorPanel():EditorPanelBase
А в этом методе передать себя в конструктор ConcreteEditorPanel
Каждый подтип EditorPanelBase будет принимать объект конкретного типа и брать и менять нужные поля без всяких приведений.

И приведений типов не надо - и структура простая. Зачем астронавтить?

Цитата:
Можно и без switch, если сериализованный объект будет содержать qualified class name или алиас (соответственно в приложении должен быть ассоциативный массив с алиасами в качестве ключей и классами в качестве значений).
Ну да.

Старый 10.11.2012, 00:16
terbooter вне форума Посмотреть профиль Отправить личное сообщение для terbooter Найти все сообщения от terbooter
  № 28  
Ответить с цитированием
terbooter

Регистрация: Oct 2006
Адрес: Novosibirsk-Kaliningrad
Сообщений: 1,278
Отправить сообщение для terbooter с помощью ICQ Отправить сообщение для terbooter с помощью Skype™
Цитата:
Сути дела это, вроде, не меняет.
Только я так и не понял, что за суть вы мне пытаетесь донести
Да, я предлагаю метод serialize() вынести в отдельный класс. В этом же классе можно сделать desirialize(), можно и в отдельном. Я считаю это не сильно важным моментом. Главное тут, что данные объекта хранятся не в потомке спрайта.

Добавлено через 1 минуту
Цитата:
В другую надо сделать свитч
Именно это я и имел ввиду, говоря что без свитча не обойтись. Не вижу разногласий.

Добавлено через 14 минут
Цитата:
Не перебор ли? Да и приведения типов не радуют.
Не проще ли сделать прямо в объекте нужного типа простые геттеры и сеттеры, которых нет у других типов.
Сделать для всех метод getEditorPanel():EditorPanelBase
А в этом методе передать себя в конструктор ConcreteEditorPanel
Каждый подтип EditorPanelBase будет принимать объект конкретного типа и брать и менять нужные поля без всяких приведений.
С приведениями типов проблемы не вижу.
Нет, не перебор. Так как мы имеем четкую и понятную сущность Property, которую можно универсально использовать в любой панели свойств. Ваш вариант предлагает рисовать для каждого случая новую панельку (Line для LinePropertyPanel и тд)

Добавлено через 18 минут
Цитата:
А в этом методе передать себя в конструктор ConcreteEditorPanel
То есть ConcrateRawObject должен уметь не только себя сериализовать (на это я еще соглашусь )
Но при этом он должен знать про класс ConcreteEditorPanel! Категорически не согласен. Не надо все валить в один бедный объект

Добавлено через 36 минут
Цитата:
А если сериализаторы решили в конструктор принимать объект и не хотят работать с другим - то пул применить и не получится.
Вы утверждаете, что нельзя сделать пул из объектов, которые принимают параметр в конструктор?

Старый 10.11.2012, 01:36
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 29  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
1. Про суть:
там были замечания по поводу того что:
- разделять сериализатор и десериализатор объекта по 2-м разным классам не является необходимостью - можно и на одном 2 метода держать.
- is создает проблемы, есть кривенький способ решить

2. По поводу свитча разногласий нет

3. По поводу панели:
Вообще, да, Ваш подход имеет право на жизнь. С одной стороны много панелек и простые компоненты, с другой - усложнённые компоненты, куча интерфейсов, но более универсальное отображение панелек.

Но я бы начал с панелки на компонент
Потом если объектов станет много - разбил бы её на части, а в компоненте в методе
писал бы не new ConcretePanel(this), а
Код AS3:
var panel:CompositePanel = new CompositePanel();
panel.addBlock(new PositionBlock(this.position))
panel.addBlock(new ColorBlock(this.color))
return panel;
Может быть даже выродилось что-то похожее на Ваш подход, видимо тут бесполезно дальше спорить если нет конкретного редактора

4.
Цитата:
А в этом методе передать себя в конструктор ConcreteEditorPanel
То есть ConcrateRawObject должен уметь не только себя сериализовать (на это я еще соглашусь )
Не должен он Вам этого Из того, что объект создаёт панель, которая с ним работает не вытекает то, что он должен ее сериализовывать или вообще хранить где-то.

Ну а то что должен знать про панель - это критично только если код объекта библиотечный. Тогда это нехило затруднит использование объекта в другом проекте. А если нет - это даже unit-тестированию не помешает. Ну не городить же свитчи и регистры соответсвия объект-панель пока и без них неплохо.

5.
Цитата:
Вы утверждаете, что нельзя сделать пул из объектов, которые принимают параметр в конструктор?
Конечно можно. Там я имел в виду, что потребуется дополнительный код чистки
Eсли сериализатор не хранит объект, то чистка не нужна и пул не нужен - сохраняем по сериализатору на тип объекта - больше одного на тип не потребуется.
Если сериализатор хранит состояние - то можно просто после вызова serialize() почистить и опять же пул не нужен.

В 2-х словах: Пул нужен, когда объектов создаётся гораздо больше, чем используется в любой момент времени. А здесь будет типов 20 - и наверняка из них штук 15 будут задействованы, и чё ради экономии 5 оставшихся организовывать пул? И может юзер разрисовался и все 20 примитивов использовал?

Нет, не так:
Здесь будет до 20 пулов, которые не будут создавать больше 1-го объекта (многие парсеры разных типов ведь - в один пул пихать нельзя). Т.е. пул работать будет, но здесь проще 20 полей с сериализаторами слепить вместо 20-ти пулов

Старый 10.11.2012, 02:30
terbooter вне форума Посмотреть профиль Отправить личное сообщение для terbooter Найти все сообщения от terbooter
  № 30  
Ответить с цитированием
terbooter

Регистрация: Oct 2006
Адрес: Novosibirsk-Kaliningrad
Сообщений: 1,278
Отправить сообщение для terbooter с помощью ICQ Отправить сообщение для terbooter с помощью Skype™
В целом согласен.
Принципиальное разногласие вижу в пунктах 3-4.
А именно, я предлагаю механизм как выделить свойства фигур, которые может изменять пользователь.
А вы предлагаете оставить это решение "на потом", а сейчас захардкодить панельки в ConcreteRawObject.
Согласен, что можно и захардкодить. Но судя по описанию задачи намечается довольно сложный векторный редактор, поэтому я предложил решение с запасом

Создать новую тему Ответ Часовой пояс GMT +4, время: 16:23.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Теги
архитектура , паттерн , Проектирование

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 16:23.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.