消除GWT活动标签样板
我正在使用GWT活动和场所框架来构建我的应用程序,结果很好。但有一件事让我恼火,那就是消除GWT活动标签样板,gwt,gwt-mvp,gwt-gin,Gwt,Gwt Mvp,Gwt Gin,我正在使用GWT活动和场所框架来构建我的应用程序,结果很好。但有一件事让我恼火,那就是ActivityMapper实现(1)接收应用程序中的所有视图(2)包含一个巨大的if/else块,用于根据接收到的位置实例化活动。随着视图数量的增加,情况只会变得更糟 我已经在用了,但我不知道我在这里怎么用 如何从我的活动apper中减少或消除样板文件?实际上,我正在为此任务使用自定义样板文件代码: public class PuksaActivityMapper implements ActivityMa
ActivityMapper
实现(1)接收应用程序中的所有视图(2)包含一个巨大的if/else块,用于根据接收到的位置实例化活动。随着视图数量的增加,情况只会变得更糟
我已经在用了,但我不知道我在这里怎么用
如何从我的
活动apper
中减少或消除样板文件?实际上,我正在为此任务使用自定义样板文件代码:
public class PuksaActivityMapper implements ActivityMapper {
private HashMap<String, ActivityContainer> mappings;
@Inject
private SearchResultActivityContainer searchResultContainer;
@Inject
private HelloActivityContainer helloContainer;
@Override
public Activity getActivity(Place place) {
ActivityContainer container = getMappings().get(place.getClass().getName());
return container.getActivity(place);
}
public HashMap<String, ActivityContainer> getMappings() {
if (mappings == null) {
mappings = new HashMap<String, ActivityContainer>();
mappings.put(ShowResultsPlace.class.getName(), searchResultContainer);
mappings.put(HelloPlace.class.getName(), helloContainer);
}
return mappings;
}
公共类puksaaActivityMapper实现ActivityMapper{
私有哈希映射;
@注入
私有SearchResultActivityContainer searchResultContainer;
@注入
私人HelloActivity容器helloContainer;
@凌驾
公共活动getActivity(地点){
ActivityContainer container=getMappings().get(place.getClass().getName());
返回容器。getActivity(地点);
}
公共HashMap getMappings(){
if(映射==null){
mappings=newhashmap();
mappings.put(ShowResultsPlace.class.getName(),searchResultContainer);
mappings.put(HelloPlace.class.getName(),helloContainer);
}
返回映射;
}
}
其中ActivityContainer是一个简单的工厂类型(从这点上讲,可以使用经典的ioc方法)
当然,现在它只是通过地图查找/填充来更改“if block”,但结合(witch当前不存在)可以完成它的工作
此外,GWT活动/场所的通用GIN模块看起来很有希望。目前还没有一个很好的答案。我脑子里有代码生成方案,但目前都是在白板上涂鸦。对于Gin用户来说,似乎一个地方范围可能很方便 Re:在if/else级联中,一种常见的方法是让Place对象实现访问者模式。例如,假设您已经为您的活动设置了AssistedInject(请原谅草率的字段注入,它只是一个草图)
类BasePlace扩展了位置{
T接受过滤器(PlaceFilter过滤器);
}
界面过滤器{
T过滤器(FooPlace);
T过滤器(BarPlace);
T过滤器(BazPlace);
}
公共类MainActivities实现ActivityMapper{
@注射Foodfactory fooMaker;
@注入酒吧制造厂;
@注射成型机;
公共活动getActivity(PlaceChangeEvent e){
return((BasePlace)e.getPlace()).acceptFilter(
新的PlaceFilter(){
活动筛选器(FooPlace){
返回fooMaker.create(place);
}
活动过滤器(酒吧场所){
返回酒吧制造者。创建(地点);
}
活动过滤器(BazPlace){
返回bazMaker.create(place);
}
})
}
}
一种可能性是让Place类层次结构的根定义一个createActivity()方法,Place子类可以返回与之关联的活动的新实例
@Override
public Activity getActivity(Place place) {
return ((BaseAppPlace)place).createActivity();
}
这样做的好处是消除了if/else块,并且在添加新位置/活动时,可以少修改一个位置。这样做的缺点是,它会通过活动创建行为污染你的Place类,即使你只是授权给Ginject。仅供将来参考,像我这样的人来到这里,仍然没有答案。 最后,我使用杜松子酒和发电机为一家工厂提供了以下解决方案 这就是我的代币现在的样子。例如:#编辑用户/id:15/type:Agent 我有一个抽象的地方,每个地方都应该从那里延伸出来
public abstract class AbstractPlace extends Place {
public abstract Activity getActivity();
}
例如:
public class EditUserPlace extends AbstractPlace {
private Long id;
private User.Type type;
//getters and setters
@Override
public Activity getActivity() {
return App.getClientFactory().getEditUserPresenter().withPlace(this);
}
}
延迟绑定的PlaceFactory接口:
public interface PlaceFactory {
Place fromToken(String token);
String toToken(Place place);
}
以及用于注册place类的注释
public @interface WithPlaces {
Class<? extends Place>[] value() default {};
}
我们需要一个定制的PlaceHistoryMapper
public class AppPlaceHistoryMapper implements PlaceHistoryMapper {
private AppPlaceFactory placeFactory = GWT.create(AppPlaceFactory.class);
public Place getPlace(String token) {
return placeFactory.fromToken(token);
}
public String getToken(Place place) {
return placeFactory.toToken(place);
}
}
最后是PlaceFactory,它将为您生成,只需将您的place类放在注释中,就可以了
@WithPlaces(value = {
HomePlace.class,
EditUserPlace.class
})
public interface AppPlaceFactory extends PlaceFactory {
}
首先,我创建了这个,所以请明星它或评论它。
我是这样做的:
public abstract class PlaceWithActivity extends Place {
public Activity getActivity();
}
然后在您的ActivityMapper中:
Public Activity get Activity(Place newPlace) {
return ((PlaceWithActivity) newPlace).getActivity();
}
你所有的位置都应该扩展PlaceWithActivity。唯一的问题是向下转换,这可能导致ClassCastException。Place有getActivity(),那么您就不必向下转换,但事实并非如此,因此您必须将它向下转换到一个这样做的类
我不喜欢的是,你必须在活动课上进行角色扮演和制作PlaceWithActivity。
如果GWT能够为我正在做的事情添加支持,那么这就没有必要了。如果它们包含一个PlaceWithActivity类,那么您就不必创建它,如果ActivityManager只需调用PlaceWithActivity类的getActivity()方法,那么您不仅不必向下转换,甚至不需要编写ActivityMapper 我找到了一个巧妙的方法。他使用visitor模式将决策逻辑推送到Place实现中,这样ActivityMapper就相当简单了。查看实现细节
@WithPlaces(value = {
HomePlace.class,
EditUserPlace.class
})
public interface AppPlaceFactory extends PlaceFactory {
}
public abstract class PlaceWithActivity extends Place {
public Activity getActivity();
}
Public Activity get Activity(Place newPlace) {
return ((PlaceWithActivity) newPlace).getActivity();
}