robotlegs 笔记
command 被事件触发,可以派发事件,映射各类。可以调用service,更新model.
mediator 可以派发,接受事件。是view跟其他层的中间人。
addViewListener监听ViewCompnent派发的事件,然后做处理。
actor 比如model,service只能派发事件。
command,mediator里面调用service,command封装业务逻辑,model封装域逻辑。
mediator监听service的返回。
这样开发者可以将应用程序特有的逻辑放到 Mediator,而避免把 View Component 耦合到特定的应用程序。
一个 View Component 是已被封装的,尽可能多地处理自己的状态和操作
。Mediators负责代表它所中介的View Component和框架交互
dispatch()发送框架事件
一个 Model 类是你的应用程序数据的看门人。应用程序里的其它 actor 通过 Model 提供的 API 请求数据。
域逻辑写在model类里面,容易复用,command的可以调用,mediator可以调用。model类通过dispatch()派发事件通知其他actor,数据变了。警告,不要监听事件。
Service类提供api来跟外部通信。service类可以调用通信工具类,比如socketManager来发送,接受数据。
sevrice的方法建议在Command中调用,而不是在Mediator中,这样可以更好的复用。当然,一个简单的方法是可以接受的。
Service只是负责将加载的数据通知(dispatch event)出去,自己并不存储数据。serveice解析数据,并且更新model,或者直接用事件分发出去.
mediator不要直接监听viewcomponent的组件的事件,比如一个按钮的点击事件,而是监听viewComponent派发的自定义事件。
永远也不要把视图逻辑放到mediator里。
在你想要挂起command的时候使用detain和release方法
A good filter is that if only the view classes care about this logic, it belongs in your view layer. If other parts of the application might need to be checked or informed, it’s controller code.
None of your normal AS3 OO solutions stop being relevant just because you’re using
Robotlegs. Well, almost none—there are two significant exceptions:
? Static Singletons. No more static public function getInstance()
? Event bubbling through the display-list (you can still bubble mouse events within
composite views, but you won’t need to rely on bubbling for wiring your applica-tion together)
? Favor composition over inheritance—composing the functionality of a class out
of smaller classes is more flexible than imposing long inheritance chains, and
Robotlegs makes composition very easy to do
? Make use of factories and helpers to keep each class adhering to the Single
Responsibility Principle—every class should have one job and do it wel
Mediators are not your view layer. Don’t imagine it as part of your view
layer—adding view logic to mediators gets messy very quickly. Just use your mediator
to translate application events into actions on the view API, and view-events into
application events,
You typically use commands to interact with your models and serv-ices.
three dependency injecition ways:
1.Constructor injection
2.Public property injection
3.Setter method injection
Limitations of custom metadata like [Inject]
If you use Flex then you’re probably already familiar with metadata tagging such as
[Bindable]. If you don’t use Flex then this syntax may be completely new to you.
The Flash Compiler is aware of its own (native) metadata—and this metadata is mostly
used at compile time in order to generate extra code that is compiled into your appli-cation. Custom metadata is different. Custom metadata isn’t parsed by the Flash Com-piler at all—in fact the compiler will remove it completely unless you ask it to keep it
(more on that later). If you’ve asked your Flash Compiler to keep this metadata it will
simply be included in your code—it doesn’t mean anything to the compiler or to the
Flash runtime.
We can find out, at runtime, what metadata a class has, and this information is what
is used to power the Robotlegs Injector. Used in this way, the [Inject] tag enables
something almost magical, but it’s important that you understand that, unlike native
metadata such as [Bindable], all custom metadata is essentially meaningless. There is
nothing special about [Inject]—we could ask you to tag your injection points with
[Frog] and get the same results—provided the Robotlegs Injector knew that [Frog] was
the metadata to look out for.
mapValue lets you control the creation of the singleton instance,
How you create this instance is up to you, with all the usual
options—new Thing(), factories,available to you.
Named rules let you create multiple rules for each class (but they’re icky)
You need to tell the compiler that you want it to keep the [Inject] and
[PostConstruct] metadata tags.
The Robotlegs swc includes the required compiler arguments for you, but when linking
against the source you will need to add the arguments yourself, and how you need to
do that depends on what you’re using to compile your code.
If an object has an [Inject]ed dependency you have to create it using the Injector
context:包含了各种依赖注入的规则,对象等等。是一个容器。
可以用不同的类来专门配置注入映射,来防止startup方法太臃肿。
override public function startup():void
{
new BootstrapConfigValues(injector);
new BootstrapModels(injector);
new BootstrapServices(injector);
new BootstrapCommands(commandMap);
new BootstrapTileSupplyCommands(commandMap);
new BootstrapClasses(injector);
new BootstrapViewMediators(mediatorMap);
addRootView();
super.startup();
}
command:
A Command is a concise single-purpose controller object
The most common purpose of a command is to update a model or kick off an operation
on a service.
Don’t work on views in commands,Instead use thatview’s own mediator to listen for events that commands dispatch,and the mediator call the view's API;
Use helper classes for shared logic
Another advantage of using commands to break your application logic
into individual actions is that you and your teammates can more easily
develop individual features in isolation.
Detain and release when you need your command to hang around
A service doesn’t store data. A model doesn’t communicate with the outside
world to retrieve data. Still—they are closely related. A model is empty without the
appropriate service, and a service has no purpose without the models
Use your API through a Command
Models and services expose an API (ideally one you’ve paired to an interface), and this
is what you use to update the state of a model, ask it for data, and call methods on your
services.
Classes that don’t dispatch events to the shared event dispatcher don’t need to extend Actor.
var creator:DatabaseCreator = injector.instantiate(DatabaseCreator),用这种方法,DatabaseCreator里的
依赖也会被注入。
Model design tips for Robotlegs:
1.Keep those responsibilities separated
2.Use strong-typed wrappers for collections
3.Never create mutually dependent models
One approach is to feed the output from a service into a factory or processor, which
then converts the raw data into AS3 native objects, and handles the creation and up-dating of the models.
Separating the parser from the actual service also allows us to vary the parser and the
service independently. When the model changes (perhaps we’ll add a ‘notes’ field to
the designs) we can update the parser without touching the code that connects to the
local SharedObject. Or, if we need to load our data from a remote service providing
JSON instead, we can pass the object created from the JSON direct to this parser. Neat.
mediator
Mediators act as bridges between your view components and the rest of your applica-tion. They allow your view components to exist without the burden of business logic
and domain logic that is better handled by other tiers of your application. Mediators
should be lightweight and carry minimal dependencies while keeping to their narrow
focus of acting as a bridge.
It is important to avoid logical code in your mediators as much as possible.
void the use of switch, for,
for each, and if statements in your mediators as much as possible. Sometimes it can’t
be avoided. You have to use one of these logical blocks to do your work. It is a warning
flag; stop and think about where this logic really belongs. Should it be a decision made
by the view? Can we move it to a command that organizes the data before sending it
to the mediator? Is this domain logic that belongs on a model that notifies the mediator?
The real key to avoiding trouble in this area is to remember that the mediator is not
your view tier. Mediators sit between your view components and the other actors in
your application.
It is much better to define and utilize API methods on the mediated view instead
of performing these actions within the mediator itself.
You should never add your event listeners to the view or the share
directly—instead the mediator contains an instance of the EventMap
of listeners in a more convenient and more reliable way.
Using the EventMap
The main benefit of using the eventMap to wire your listene
when the view leaves the stage and the mediator is destroyed
be automatically cleaned up, avoiding pesky memory leaks.
Mediators are equipped with two convenient methods for adding listeners to the
EventMap. These methods are addViewListener() and addContextListener().
Never put view logic into the mediator
小技巧:
1,如果context里的映射配置过多,可以用专门类,或者command来做配置。减少startup方法的代码量。
模块之间通信
可以考虑使用共享的eventdispatcher,也就是全局的。或者使用stage直接沟通,简单高效。