在当前我们配置一个数据源给页面,用的是
MockDataSource.
但是当我们想要提供一个真正的数据源,想用一个
RealDataSource
的时候。难道我们要一个一个类的去替换他们吗?这肯定不是很好的设计。
最好的做法是在页面中使用接口:
@ApplicationState
private IDataSource dataSource;
这样所有实现
IDataSource
的类都可以被当作一个
ASO
来使用。但是我们怎么让
Tapestry
去实例化一个接口作为
ASO
呢?接下来我们就要寻找这个答案。
我们将会看到
Tapestry
一些名字很
BT
的特殊的类,不过别害怕,它们的逻辑是很简单的
起初,在应用中需要一个名字叫
package com.packtpub.celebrities.serivces
的包。添加一个叫
AppModule
的类,这个类由
maven
产生的。现在我们就去使用这个类,浏览一下代码,我们可以这个地方与
Tapestry
的工作很吻合
-------confingure
。我们可以扩大现有的业务,甚至定制属于自己的业务。
我们现在去改变
Tapestry
管理
ASO
的方式。我们值需要增加一个方法,
contributeApplicationStateManager
,从而有助于我们用自己的方式来管理
ASO
。
public void contributeApplicationStateManager( MappedConfiguration<Class, ApplicationStateContribution>configuratio) { ApplicationStateCreator<IDataSource> creator = new ApplicationStateCreator<IDataSource>() { public IDataSource create() { return new MockDataSource(); } }; configuration.add(IDataSource.class, new ApplicationStateContribution("session", creator)); }
首先,创建联合类型为
IDataSouece
类型的
ApplicationStateCeator
接口的实现。
ApplicationStateCreator<IDataSource> creator = ...
为此,我们使用了匿名内部类。我们创建了一个实现了
applicationstatecreator
接口的类,在这里这个接口和
IDataSource
类型联合
—
这个类型就是页面中被当作
ASO
的类型。我们不用去关心用来创建这个实例的
IDataSource
的类名。
ApplicationStateCreator
只有一个方法,
create()
,这个方法会返回一个与这个接口关联的类型的实例,你也可以在这个方法中自定义配置,比如得到一些资源,把他们当作类构造器的参数传出去。等等
,这里是非常简单的:
public IDataSource create()
{
return new MockDataSource();
}
如果象换成其他的数据源只要在这里修改就可以。
最后,我们把新创建的东西给应用的配置,再次和
ASO
的类型联合。
现在我们把所有把
MockDataSource
当作
SAO
使用的的地方替换为
IDataSource
,现在当你请求这个
ASO
的时候,
Tapestry
会检查它的配置看看是否有与请求
IDataSource
类型匹配的创建者。我们刚刚提供了一个,所以他能很好的工作。