【问题标题】:Design Patterns for alleviating / changing the visibility of an object用于减轻/改变对象可见性的设计模式
【发布时间】:2019-11-06 10:01:26
【问题描述】:

问题

我一直在这个范式中运行,我必须编写maybeUpdateEnabled 形式的函数,在其中我更改一个决定可见性的变量,并且必须检查其他变量的负载。

示例

假设我有以下数据(为方便起见,这里表示为字符串):

["apple", "pear", "tomato", "celery", "red pepper"]

我为用户提供了一个带有两个切换按钮的 GUI,一个用于过滤掉所有红色的东西,一个用于过滤掉所有蔬菜的东西。用户首先过滤掉所有的红色,然后过滤掉所有的蔬菜,只剩下梨。当用户随后切换红色开关时,最初被过滤掉的red peppers 应该仍然不可见,因为它们仍然通过蔬菜过滤器被隐藏。

问题

是否有任何设计模式可以帮助缓解这种情况?我正在考虑使用位掩码或某种堆栈,但我认为我无法从逻辑上避免 maybeUpdate 范式,这对我来说是一种可怕的代码气味。

编辑

我还想补充一点,这不一定是“我该怎么做”的问题,而是“我如何才能让这不让人头疼”。我可以拥有任何 n 数量的字段,但没有一个特别保证哪些条件可以过滤掉任何 m 数量的对象。我在生产中对此进行了临时修复,但我想进行重构以提供干净的 API,而无需重构几乎所有内容。

编辑 2

虽然我不能发布代码,但我绝对可以告诉你,正在使用一堆 JFXToggleButtons,并且侦听器正在连接到 selectedProperty“信号”,在我看来,这正在创建一个非常紧的视图、模型和控制器之间的耦合,因为视图和控制器实际上是相同的底层数据结构和类(这很糟糕)。在没有 GUI 的情况下更改属性具有自动更新控制器的好处,但不幸的是,对于每个属性更改都会发出更改,根据上述编辑,效率非常低(是的,我已经对其进行了分析)。

【问题讨论】:

  • Java 的内置功能(例如流)可以轻松满足您的要求。您可能想在您的问题中添加一些相关的 Java 代码。
  • @jfh 我不是在谈论复制粘贴代码,我是在谈论减少任何可能特定于您的业务的问题
  • 您的问题与设计模式无关。 BitmaskStack 不是设计模式。堆栈是一种数据结构,位掩码是一种二进制操作。
  • 有趣。我可以发誓你的问题是这样的:我想使用切换按钮过滤一些项目。 “是否有任何设计模式可以帮助缓解这种情况?我正在考虑使用位掩码或某种堆栈......”。老实说,这听起来不像您所说的:“我有这个架构问题导致我遇到维护问题,我该如何缓解呢?”。你应该明确你需要什么,也许改写你的问题。
  • 我还想知道您有哪些密码,您无法简单地表示您的代码结构和绑定方式。以及为什么“绝对做不到”。绝对不清楚到目前为止您拥有什么以及您想要什么,这就是您没有答案的原因。您询问过滤,但您的意思是架构。这很令人困惑。无意冒犯,但你应该修改你的问题。

标签: java javafx design-patterns


【解决方案1】:

要过滤集合对象,过滤器需要一个条件。此条件必须是要过滤的对象的属性。过滤纯字符串时,标准可以是词汇、语法、句法或语义。

您显然对字符串的语义感兴趣。为了使事情更容易,您应该使用对象来表示字符串数据。过滤条件可以是EnumSet<E> 形式的标签列表。

首先定义一个可用标签的列表。您可以将此列表公开给 UI,也可以通过 UI 使其可扩展(扩展标记列表仍会使您的数据对象关闭以供修改):

public enum Tags
{
  RED, YELLOW, GREEN, VEGETABLE, FOOD, FRUIT, MEAT, SWEET, HOT, SPICEY
}

然后准备过滤的数据对象:

public interface IFilterable
{
  EnumSet<Tags> getTags();
  void setTags(EnumSet<Tags> tags);
}

public class DataObject implements IFilterable
{
  private EnumSet<Tags> tags; 
  public EnumSet<Tags> getTags() { 
    return this.tags; 
  }

  public void setTags(EnumSet<Tags> tags) { 
    this.tags = tags; 
  }
}

现在可以通过使用流或javafx.collections.transformation.FilteredList&lt;E&gt; 类轻松实现过滤。

要仅显示红色蔬菜(例如,当用户修改过滤器时),请使用:

public static void main(String[] args) {
  ObservableList<DataObject> unfilteredObjects = FXCollections.observableArrayList(new DataObject(EnumSet.of(Tags.RED, Tags.VEGETABLE)), new DataObject(EnumSet.of(Tags.RED, Tags.FRUIT)));

  // A filtered collection that contains only red vegetables
  // In this case the size of redVegetables will be 1
  EnumSet<Tags> filterCriteria = EnumSet.of(Tags.RED, Tags.VEGTABLE);
  Predicate<DataObject> filterPredicate = dataObject -> dataObject.getTags().containsAll(filterCreiteria);
  FilteredList<DataObject> redVegetables = new FilteredList<>(unfilteredObjects, filterPredicate);
}

当您现在将ListView 绑定到ObservableList(或FilteredList,因为它实现了ObservableList)时,只会显示过滤的项目,而排除的项目将自动从显示中消失。

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 2012-03-11
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    • 2011-08-01
    相关资源
    最近更新 更多