1

我已经实现了一系列类来使用JSFPrimeFaces管理搜索/详细信息页面。更详细地说,我创建了一个抽象类SearchDetailView<C extends BaseView, M>以集中搜索/详细信息页面的常用功能。

简而言之,我有一个MyView扩展 base的类SearchDetailView。现在我想添加另一个行为MyView,即Confirm Dialog

我想知道我必须使用什么设计模式?我打算使用设计模式Decorator,但我不需要在运行时添加新行为,但我已经知道行为MyView需要什么。

我不能扩展两个类(显然),但我不喜欢有很多“基”类的组合。我想创建第二个抽象类ConfirmDialogDecorator,以便“以编程方式”添加额外的功能。

那么,我问你哪种设计模式为类添加了行为?

实际上我的代码如下:

public abstract class SearchDetailView<C extends BaseController, M> extends BaseView {
    [...]
}

public abstract class ConfirmDialogDecorator<C extends BaseController, M> extends SearchDetailView<C, M> { 

    public void showDialog(final String message) { [...] }

}

public class MyView extends ConfirmDialogDecorator<MyController, MyModel> { 
    [...]
}

但我想ConfirmDialogDecoratorSearchDetailView. 任何想法?谢谢。

更新: 正如两个答案中所建议的,我使用了 Java 8 默认方法(Mixin 模式?):

public interface ConfirmDialog {

    Dialog dialog = new Dialog();

    default public String getConfirmMessage() {
        return "Do you confirm?";
    }

    default String getWidgetVar() {
        return "confirmDialog";
    }

    public void onConfirm();

    default void showDialog(final String message) {
        dialog.setWidgetVar(this.getWidgetVar());
        dialog.setMessage(message);
        dialog.showDialog(message);
    }

    class Dialog {

        private String message;
        private String widgetVar;

        String getMessage() {
            return message;
        }

        void setMessage(final String message) {
            this.message = message;
        }

        public String getWidgetVar() {
            return widgetVar;
        }

        public void setWidgetVar(final String widgetVar) {
            this.widgetVar = widgetVar;
        }

        void showDialog(final String message) {
            final PrimeFaces current = PrimeFaces.current();
            current.executeScript("PF('" + this.widgetVar + "').show();");
        }
    }
}

public class MyView extends SearchDetailView<MyController, MyModel>
    implements ConfirmDialog {

    public void onSave() {
       if(!this.someCheck()) {
          this.showDialog("Are you really sure?");
       } else {
          this.save();
       }
    }

    @Override
    public void onConfirm() {
        this.save();
    }

    public void save() {
       // The save
    }

}

在 xhtml 中:

<p:confirmDialog widgetVar="confirmDialog" global="true">
    <h:outputText value="#{myView.confirmMessage}" />
    <p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check" />
    <p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times" />
</p:confirmDialog>
4

2 回答 2

3

我打算使用设计模式Decorator,但我不需要在运行时添加新行为,但我已经知道MyView需要什么行为。

接着

我想创建第二个抽象类,例如 ConfirmDialogDecorator,以便“动态地”添加额外的功能。

你不说一件事和它相反吗?
您在编译时知道装饰可能性的事实并不意味着该模式没有被适应。

但我想将 ConfirmDialogDecorator 与 SearchDetailView 分开。

装饰器也是子类化和避免类层次结构的替代方案。
通过引入装饰器接口来使用该模式可能是满足您要求的正确方法。

作为替代,Java 8 在接口中引入了默认方法的概念,允许向实现它的类添加行为。
在某种程度上,我们可以将其视为一种在没有子类化的情况下用额外的行为来装饰静态类的方法。请注意,由于接口不能定义实例字段,默认方法也不能使用它。所以你应该根据这个约束考虑这个替代方案。

于 2019-02-05T08:50:44.543 回答
1

通常在没有继承的情况下向类添加功能时使用mixim/trait概念。

您可以使用Java 中的默认方法或方面对象编程来实现此概念

于 2019-02-05T08:56:21.153 回答