Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
消除GWT活动标签样板_Gwt_Gwt Mvp_Gwt Gin - Fatal编程技术网

消除GWT活动标签样板

消除GWT活动标签样板,gwt,gwt-mvp,gwt-gin,Gwt,Gwt Mvp,Gwt Gin,我正在使用GWT活动和场所框架来构建我的应用程序,结果很好。但有一件事让我恼火,那就是ActivityMapper实现(1)接收应用程序中的所有视图(2)包含一个巨大的if/else块,用于根据接收到的位置实例化活动。随着视图数量的增加,情况只会变得更糟 我已经在用了,但我不知道我在这里怎么用 如何从我的活动apper中减少或消除样板文件?实际上,我正在为此任务使用自定义样板文件代码: public class PuksaActivityMapper implements ActivityMa

我正在使用GWT活动和场所框架来构建我的应用程序,结果很好。但有一件事让我恼火,那就是
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();
 }