首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wicket通用组件设计模式

Wicket通用组件设计模式
EN

Stack Overflow用户
提问于 2011-12-14 05:34:37
回答 3查看 1.4K关注 0票数 1

我正在实现一些通用组件,我只是想知道我的设计模式是否有意义,以及是否有任何改进可做。例如,这里有一个通用面板,可用于过滤内容:

代码语言:javascript
复制
/**
 * Abstract class for textfields used for filtering. When overriding abstract method onUpdateFilter, the first thing
 * that must be done is to set the paramsobject, or else filtering wont work.
 * @author fred
 *
 */

public abstract class FilterFormPanel extends Panel {

    private static final long serialVersionUID = 1L;
    private FilterForm filterForm;
    private Object paramsObject; //this is object because paramsobjects differ depending on entity type

    public FilterFormPanel(String id) {
        super(id);
        filterForm = new FilterForm("filterForm");
        add(filterForm);
    }

        public String getFilterString(){
        return filterForm.getFilterString();
    }

    public void setParamsObject(Object paramsObject){
        this.paramsObject = paramsObject;
    }

    /**
     *For developers to implement in class that contains the correct references to params and facade objects, dataviews etc.
     *e.g. they could do params.setFilter(<reference to an instance of this class>.getFilterString() and ajax stuff too) 
     */
    public abstract void onUpdateFilter(AjaxRequestTarget target, Object paramsObject);

    private class FilterForm extends Form<Void> {

        private static final long serialVersionUID = 1L;
        private transient String filterString;

        public FilterForm(String id) {
            super(id);
            final TextField<String> filterTextField = new TextField<String>("filterTextField", new PropertyModel<String>(this, "filterString")); //textField for user to enter filter string
            add(filterTextField);

            add(new AjaxButton("filterButton") { //button to click for performing overriden method
                private static final long serialVersionUID = 1L;
                @Override
                protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                    onUpdateFilter(target, paramsObject);
                }
            }); 
        }

        public String getFilterString(){
            return filterString;
        }   
    }
}

用于另一个类中如下:

代码语言:javascript
复制
    filterFormPanel = new FilterFormPanel("filterFormPanel"){

        private static final long serialVersionUID = 1L;

        @Override
        public void onUpdateFilter(AjaxRequestTarget target, Object paramsObject) {
            filterFormPanel.setParamsObject(params);
            params.setFilterString(filterFormPanel.getFilterString());
            //ajax stuff
            target.addComponent(dataViewContainer);
            nav.setVisible(dataProvider.size()!=0);
            target.addComponent(nav);
            emptyLabel.setVisible(dataProvider.size()==0);
            target.addComponent(emptyLabel);
        }

    };

    settingsContainer.add(filterFormPanel);

当重写方法时,第一件事就是被迫使用setParamsObject方法,这是一种恼人的做法。是否有更好的方法来实现对该对象的引用?这是在wicket中实现可重用和相对通用的组件的一种通用方法吗?任何反馈都将是非常感谢的,我相信这里还有改进的余地。

编辑I:只是为了一些上下文,我所做的是实现这样的页面

在这里,我向用户提供一个数据视图和筛选它的选项。有很多不同实体的页面,但是GUI组件可以并且应该尽可能地泛化,以免违反DRY。示例代码显然是页面的筛选器、文本字段和按钮部分。

编辑二:如果可能的话,我希望这个组件能够更松散地耦合,例如,使它能够完成完全不同的事情,而不仅仅是修改一个params对象(例如,在另一个情况下,我需要更新两个params对象,那么我就不能使用这个面板)。表单中的onSubmit方法现在需要对overriden方法中使用的对象的引用是事先知道的。有没有办法不这样做,或者动态地设置这些对象的存在和/或类型?

编辑三:关键是这个面板的核心功能实际上是只允许用户

  • 输入字符串
  • 通知,并在用户单击该按钮时将对该字符串的访问权限授予系统的其他部分。

“系统的其他部分”对字符串所做的事情不应该真的涉及到这个面板,但是就像现在一样,它被耦合到“系统的另一部分”必须在其上执行某些操作的params对象。如果可能的话,这就是我想要摆脱的耦合。我可能还想使用这个面板中的字符串来打印控制台,或者使用它来执行其他任意任务。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-14 07:30:39

实际上,即使我一开始没有意识到这一点,但只要简单地这样做,就可以很容易地做到这一点:

代码语言:javascript
复制
/**
 * Abstract class for textfields used for filtering.
 * @author fred
 *
 */

public abstract class FilterStringPanel extends Panel {

private static final long serialVersionUID = 1L;
private FilterForm filterForm;

public FilterStringPanel(String id) {
    super(id);
    filterForm = new FilterForm("filterForm");
    add(filterForm);
}

public String getFilterString(){
    return filterForm.getFilterString();
}

/**
 *For developers to implement in class that contains the correct references to params and facade objects, dataviews etc.
 *e.g. they could do params.setFilter(<reference to an instance of this class>.getFilterString() and ajax stuff too) 
 */
public abstract void onUpdateFilter(AjaxRequestTarget target);

private class FilterForm extends Form<Void> {

    private static final long serialVersionUID = 1L;
    private transient String filterString;

    public FilterForm(String id) {
        super(id);
        final TextField<String> filterTextField = new TextField<String>("filterTextField", new PropertyModel<String>(this, "filterString")); //textField for user to enter filter string
        add(filterTextField);

        add(new AjaxButton("filterButton") { //button to click for performing overriden method
            private static final long serialVersionUID = 1L;
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
                onUpdateFilter(target);
            }
        }); 
    }

    public String getFilterString(){
        return filterString;
    }   
}
}

然后以这样的方式实现:

代码语言:javascript
复制
    settingsContainer.add(new FilterStringPanel("filterStringPanel"){
        private static final long serialVersionUID = 1L;
        @Override
        public void onUpdateFilter(AjaxRequestTarget target) {
            params.setFilterString(getFilterString());
            target.addComponent(dataViewContainer);
            nav.setVisible(dataProvider.size()!=0);
            target.addComponent(nav);
            emptyLabel.setVisible(dataProvider.size()==0);
            target.addComponent(emptyLabel);
        }
    });

这样,我们就不需要向任何对象发送任何引用(例如,params对象或wicket组件,这些组件需要被用于AJAX更新),而且我们可以任意重用这个面板!

票数 0
EN

Stack Overflow用户

发布于 2011-12-14 06:20:48

您可以使用类的构造函数来设置对象。

如果允许paramsObject使用Java (因此名为:),将是一种更通用的方法。您可以对实体进行超类,也可以让它们实现接口。

票数 3
EN

Stack Overflow用户

发布于 2011-12-14 06:48:40

我在一个使用Wicket的web应用程序上工作了3年多(开始使用1.3.x,现在在1.4.x下,并计划在几周内升级到1.5.x )。您正在使用的方法是我们内部使用的方法。我们经常使用抽象类来表示公共面板。我们所做的唯一的事情就是罗奇在他的回答中所说的,我们使用了大量的泛型来尽可能多地推断类型参数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8499903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档