设计模式丰富了新功能

时间:2019-02-05 08:34:52

标签: java oop design-patterns decorator-pattern

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

简而言之,我有一个MyView类,它扩展了基础SearchDetailView。 现在,我想向MyView添加另一个行为,即确认对话框

我想知道我必须使用哪种设计模式?,我打算使用设计模式 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>

2 个答案:

答案 0 :(得分:3)

  

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

然后

  

我想创建另一个抽象类,例如ConfirmDialogDecorator   为了“动态”添加额外的功能。

你不是说一句话吗?相反吗?
您知道在编译时可能进行装饰的事实并不意味着该模式不适用。

  

但是我想将ConfirmDialogDecorator与SearchDetailView分开。

Decorator还是子类化的替代方法,避免了类层次结构。
通过引入装饰器接口使用模式可能是满足您需求的正确方法。

作为替代Java 8在接口中引入了默认方法的概念,该方法允许向实现它的类中添加行为。
在某种程度上,我们可以将其视为用其他行为来装饰静态类而无需子类化的一种方法。请注意,由于接口无法定义实例字段,因此默认方法也无法使用它。因此,您应根据此约束条件考虑使用此替代方法。

答案 1 :(得分:1)

通常使用mixim/trait概念来向不继承的类添加功能。

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