Окинув взглядом Parsley 2, я получил кучу интересных идей. Фреймворк на 80% делает то, что мне нужно. Но остальные 20 полностью не совместимы с моим видением счастья. Более того, стиль Parsley кардинально отличается от моего стиля программирования. Надо будет узнать, есть подозрение, что такой стиль принят у Java разработчиков.
В итоге придется переписывать.
Итак, что мне нужно. Продолжая ликбез об IoC, и принимая во внимание интересные фишки Parsley, имеем следующее.
Reflection.
Под reflection понимается возможность программы иметь представление о классах, их методах и свойствах во время исполнения. Во флэше reflection реализуется через flash.utils.describeType(). Удобная надстройка, парсящая XML возвращаемый этой функцией у меня почти есть.
Все дальнейшее базируется на готовом reflection framework.
Convention over configuration.
Знакомый слоган руби программистов. Проще делать все по соглашению, чем писать огромные конфиги каждый раз. 60% этих конфигов все равно будет переходить из приложения в приложение и является ни чем иным как записью этого “соглашения”. Нужно максимально воплотить этот принцип.
IoC Container.
Контейнер для сборки объектов в единое приложение. Сборка конфигурируется через XML, поведение через Metadata.
Часть конфига.
<object type="BookShelf"> <book> <title>Title</title> <page/> <page/> </book> </object>
class BookShelf {
[Of("package.Book")]
public var books: Array
}
class Book {
var title: String;
[Of("package.Page")]
var pages: Array;
}
class Page {}
Пример использования мета данных, который говорит, что это массив элементов класса package.Book. В конфиге написано, что создаем объект класса BookShelf, добавляем в него книгу (тэг <book>). Класс BookShelf имеет public массив books, обозначенный как содержащий элементы класса package.Book. С помощью рефлекшна контейнер соображает, что book добавляется в массив books — создается экземпляр класса package.Book и добавляется в массив. У класса package. Book есть публичное свойство title, которое устанавливается в “Title”, и массив pages, в который помещаются два экземпляра класса package.Page.
Среди важных метатэгов хочу выделить [Inject], [ConstructorInject], [Init].
Пример.
<object type="A"> <object type="B"/>
public class A{}
public class B{
[Inject]
public var ofA: A;
[Init]
public function initFunc(){}
}
В конфиге контаекста имеем два объекта: объект класса A и объект класса B. Метадата на классе B говорит, что в свойство ofA нужно инъектировать объект типа A, который предполагается существует в контейнере в единственном экземпляре. Метадата [Init] говорит контейнеру выполнить initFunc, когда конфигурирование объекта закончится.
Плюс к этому еще толпа интересных тэгов.
Думаю, метаданные должны мапаться в тэги, так как у тэгов все же возможности больше, например вложенность.
Factory.
Каждое определение объекта в контейнере на самом деле интерпретируется как фактори, то есть объект, который умеет этот объект создавать. Это можно использовать, когда нам нужно создавать сконфигурируемые объектные шаблоны (чаще визуальных компонентов).
Модель событий.
События, передаваемые через контекст, можно помечать прямо на объектах и пусть контейнер сам заботится о них. Примерно так.
[Event(...)]
[ManagedEvents("eventName")]
public class someClass {
[EventHandler]
public function handler( evt: SomeEvent ) {}
}
Метадата говорит нам, что класс someClass может диспатчить событие eventName, которое должно обрабатываться в контейнере, и желает получать события класса SomeEvent, которые обрабатываются функцией handler. Таким образом, контейнер сам связывает объекты нужным им событиям. И объекты ничего друг о друге не знают и никак не зависят.
MVC.
На этом всем строится MVC фреймворк.
На самом деле, все уже и так максимально разделено, но все же мне нужна некая концепция
- Визуальные компоненты на stage
- Компоненты с данными
- Действия, чтобы визуальные компоненты напрямую данные не изменяли
Это возвращает нас к концепции похожей на MVC.
Expressions.
Нужен (да, собственно, уже есть) некий фреймворк для разбора простых математических выражений. Сейчас он используется в текущем MVC воплощении в визуальных компонентах. Например, вот часть конфига.
<view name=".." class=".." parent=".."> <property name="yRule">H-42</property> <property name="inactiveYRule">H</property> </view>
yRule — правило, по которому считается y компонента. H — это, в общем, stage.stageHeight.
inactiveYRule — правило, которое выполняется, когда приложение перешло в неактивное состояние.
И последнее.
Перед тем, как что-то кодить, некоторое время я буду еще прикидывать в уме use cases. Хотелось бы услышать комментарии по поводу написанных требованийпожеланий, если это кто-то читает еще.

